daimon 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/cli.js +98 -88
  3. package/dist/dashboard/browser/chunk-2LMH5KDX.js +5 -0
  4. package/dist/dashboard/browser/{chunk-6Z4FDREI.js → chunk-2QORICNU.js} +1 -1
  5. package/dist/dashboard/browser/{chunk-UUJWPV5O.js → chunk-36JZZZCV.js} +1 -1
  6. package/dist/dashboard/browser/{chunk-4KVYA2AQ.js → chunk-3S7OJ77P.js} +1 -1
  7. package/dist/dashboard/browser/{chunk-TGSV7ZHM.js → chunk-42QQHEGP.js} +1 -1
  8. package/dist/dashboard/browser/chunk-4L223A7A.js +1 -0
  9. package/dist/dashboard/browser/{chunk-EBGPIJ7S.js → chunk-532NB4ME.js} +1 -1
  10. package/dist/dashboard/browser/{chunk-X4RGWMLE.js → chunk-6CP6NCA6.js} +2 -2
  11. package/dist/dashboard/browser/chunk-6OMBXV4F.js +1 -0
  12. package/dist/dashboard/browser/chunk-6YXOOFGY.js +1 -0
  13. package/dist/dashboard/browser/{chunk-VMW35ZNT.js → chunk-AHO3BCLI.js} +1 -1
  14. package/dist/dashboard/browser/{chunk-CIQNXWDY.js → chunk-ASK7FG27.js} +1 -1
  15. package/dist/dashboard/browser/{chunk-AGN2F6JP.js → chunk-BCGQJHY3.js} +1 -1
  16. package/dist/dashboard/browser/{chunk-ACPSBF55.js → chunk-BDTAVYPH.js} +1 -1
  17. package/dist/dashboard/browser/{chunk-FZLMX6EY.js → chunk-BFBXHJEF.js} +1 -1
  18. package/dist/dashboard/browser/{chunk-B2DPS6BL.js → chunk-BKYXU3OY.js} +1 -1
  19. package/dist/dashboard/browser/{chunk-UC7AWK4C.js → chunk-BPUIUSAU.js} +1 -1
  20. package/dist/dashboard/browser/{chunk-6MTVWBQQ.js → chunk-C6SNIY22.js} +1 -1
  21. package/dist/dashboard/browser/{chunk-3ZFFKHPU.js → chunk-CCRYWDXZ.js} +1 -1
  22. package/dist/dashboard/browser/{chunk-JWXROQJJ.js → chunk-DNHNU64I.js} +1 -1
  23. package/dist/dashboard/browser/{chunk-FRKUCFVI.js → chunk-DRBVSI3B.js} +1 -1
  24. package/dist/dashboard/browser/{chunk-RNUJZTKS.js → chunk-EXOJOB6H.js} +2 -2
  25. package/dist/dashboard/browser/chunk-EYOED3X7.js +2 -0
  26. package/dist/dashboard/browser/{chunk-3EPFSBJ2.js → chunk-G3IBZZQH.js} +1 -1
  27. package/dist/dashboard/browser/chunk-H3HRZLHG.js +4 -0
  28. package/dist/dashboard/browser/chunk-H5GKWN4K.js +1 -0
  29. package/dist/dashboard/browser/{chunk-KRC72WWY.js → chunk-HVK4GEK7.js} +1 -1
  30. package/dist/dashboard/browser/{chunk-7LKM244H.js → chunk-HYIZY5FQ.js} +1 -1
  31. package/dist/dashboard/browser/chunk-ITSOVQEA.js +1 -0
  32. package/dist/dashboard/browser/{chunk-WOMCRDMJ.js → chunk-JODWQVMA.js} +1 -1
  33. package/dist/dashboard/browser/chunk-LAMOHX23.js +1 -0
  34. package/dist/dashboard/browser/chunk-NMKAKRON.js +1 -0
  35. package/dist/dashboard/browser/{chunk-F3FCHBFQ.js → chunk-NY5IR366.js} +1 -1
  36. package/dist/dashboard/browser/{chunk-NVL5HFLU.js → chunk-OOQPWG6B.js} +1 -1
  37. package/dist/dashboard/browser/{chunk-SR4HVFOB.js → chunk-P3Q7RWT5.js} +1 -1
  38. package/dist/dashboard/browser/{chunk-YHBNUNU3.js → chunk-PVPELZPO.js} +1 -1
  39. package/dist/dashboard/browser/{chunk-66VYPESU.js → chunk-QHXOUNPA.js} +1 -1
  40. package/dist/dashboard/browser/{chunk-VHALTUPL.js → chunk-RMV7CR6Y.js} +1 -1
  41. package/dist/dashboard/browser/chunk-RQSDQXNY.js +1 -0
  42. package/dist/dashboard/browser/chunk-RWX5JIT4.js +1 -0
  43. package/dist/dashboard/browser/{chunk-R7VSXL63.js → chunk-SXE7REUK.js} +1 -1
  44. package/dist/dashboard/browser/chunk-TLCLILNG.js +4 -0
  45. package/dist/dashboard/browser/chunk-UAIWZYHN.js +1 -0
  46. package/dist/dashboard/browser/chunk-UFTWVSEC.js +2 -0
  47. package/dist/dashboard/browser/{chunk-RWXAGDGT.js → chunk-UXLEE3F2.js} +1 -1
  48. package/dist/dashboard/browser/{chunk-K6PUQAFE.js → chunk-XPP3TYS2.js} +1 -1
  49. package/dist/dashboard/browser/{chunk-PRLUGTKR.js → chunk-YFYMS5EE.js} +1 -1
  50. package/dist/dashboard/browser/chunk-YPVVBWNF.js +1 -0
  51. package/dist/dashboard/browser/{chunk-BBTQXZIS.js → chunk-Z3XFJOYG.js} +1 -1
  52. package/dist/dashboard/browser/index.html +2 -2
  53. package/dist/dashboard/browser/main-EENULCI5.js +1 -0
  54. package/dist/main.js +55 -51
  55. package/dist/mcp.js +3 -3
  56. package/package.json +4 -2
  57. package/dist/dashboard/browser/chunk-55AO3FMG.js +0 -1
  58. package/dist/dashboard/browser/chunk-FD3BW2ZN.js +0 -1
  59. package/dist/dashboard/browser/chunk-GMEW64AS.js +0 -1
  60. package/dist/dashboard/browser/chunk-HXX2OUOE.js +0 -1
  61. package/dist/dashboard/browser/chunk-HZNVO3JE.js +0 -1
  62. package/dist/dashboard/browser/chunk-K2SFF47Z.js +0 -5
  63. package/dist/dashboard/browser/chunk-K5WKBG55.js +0 -1
  64. package/dist/dashboard/browser/chunk-LBWOIG7N.js +0 -5
  65. package/dist/dashboard/browser/chunk-O76B43BY.js +0 -4
  66. package/dist/dashboard/browser/chunk-QYIYT4YU.js +0 -1
  67. package/dist/dashboard/browser/chunk-RXOAYCKI.js +0 -2
  68. package/dist/dashboard/browser/chunk-WRX32YWH.js +0 -1
  69. package/dist/dashboard/browser/main-YAROJLJV.js +0 -1
package/dist/mcp.js CHANGED
@@ -1,4 +1,4 @@
1
- import{McpServer as et}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as rt}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as a}from"zod";import w from"node:fs";import b from"node:path";import k from"node:os";import{fileURLToPath as H}from"node:url";var B=H(import.meta.url),M=b.dirname(B);function L(){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:b.join(k.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:b.join(k.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]}},dashboard:{theme:"auto",density:"comfortable"},errorRetention:{maxAgeMs:864e5},plugins:{dir:null}}}function C(r){return r.startsWith("~/")||r.startsWith("~\\")?b.join(k.homedir(),r.slice(2)):r==="~"?k.homedir():r}function T(r,s){if(!r||typeof r!="object")throw new Error(`Config at ${s} is not a JSON object`);let t=r,n=L();if(t.searchRoots!==void 0){if(!Array.isArray(t.searchRoots)||!t.searchRoots.every(e=>typeof e=="string"||e&&typeof e=="object"&&typeof e.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${s})`);n.searchRoots=t.searchRoots}if(t.portRange!==void 0){if(!Array.isArray(t.portRange)||t.portRange.length!==2||typeof t.portRange[0]!="number"||typeof t.portRange[1]!="number"||t.portRange[0]>t.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${s})`);n.portRange=[t.portRange[0],t.portRange[1]]}if(t.apiPort!==void 0){if(typeof t.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${s})`);n.apiPort=t.apiPort}if(t.overrides!==void 0){if(typeof t.overrides!="object"||t.overrides===null||Array.isArray(t.overrides))throw new Error(`Config "overrides" must be an object (${s})`);n.overrides=t.overrides}if(t.autoStart!==void 0){if(!Array.isArray(t.autoStart)||!t.autoStart.every(e=>typeof e=="string"))throw new Error(`Config "autoStart" must be an array of strings (${s})`);n.autoStart=t.autoStart}if(t.profiles!==void 0){if(typeof t.profiles!="object"||t.profiles===null||Array.isArray(t.profiles))throw new Error(`Config "profiles" must be an object (${s})`);for(let[e,p]of Object.entries(t.profiles))if(!Array.isArray(p)||!p.every(c=>typeof c=="string"))throw new Error(`Config "profiles.${e}" must be an array of strings (${s})`);n.profiles=t.profiles}if(t.tags!==void 0){if(typeof t.tags!="object"||t.tags===null||Array.isArray(t.tags))throw new Error(`Config "tags" must be an object (${s})`);n.tags=t.tags}if(t.autoRestart&&typeof t.autoRestart=="object"&&(n.autoRestart={...n.autoRestart,...t.autoRestart}),t.healthProbe&&typeof t.healthProbe=="object"&&(n.healthProbe={...n.healthProbe,...t.healthProbe}),t.logs&&typeof t.logs=="object"&&(n.logs={...n.logs,...t.logs},n.logs.dir=C(n.logs.dir)),t.depends&&typeof t.depends=="object"&&!Array.isArray(t.depends)){for(let[e,p]of Object.entries(t.depends))if(!Array.isArray(p)||!p.every(c=>typeof c=="string"))throw new Error(`Config "depends.${e}" must be an array of strings (${s})`);n.depends=t.depends}if(typeof t.cascadeRestart=="boolean"&&(n.cascadeRestart=t.cascadeRestart),t.history&&typeof t.history=="object"&&(n.history={...n.history,...t.history},n.history.path=C(n.history.path)),t.notifications&&typeof t.notifications=="object"&&(n.notifications={...n.notifications,...t.notifications}),t.staleDetect&&typeof t.staleDetect=="object"&&(n.staleDetect={...n.staleDetect,...t.staleDetect}),typeof t.headless=="boolean"&&(n.headless=t.headless),t.envFiles&&typeof t.envFiles=="object"&&!Array.isArray(t.envFiles)&&(n.envFiles=t.envFiles),t.requestLog&&typeof t.requestLog=="object"&&(n.requestLog={...n.requestLog,...t.requestLog}),t.metrics&&typeof t.metrics=="object"&&(n.metrics={...n.metrics,...t.metrics}),t.editor&&typeof t.editor=="object"){let e=t.editor.scheme;typeof e=="string"&&e.trim()&&(n.editor={scheme:e.trim()})}if((typeof t.apiToken=="string"||t.apiToken===null)&&(n.apiToken=t.apiToken),t.output&&typeof t.output=="object"){let e=t.output;(e.format==="compact"||e.format==="full")&&(n.output.format=e.format),typeof e.ndjson=="boolean"&&(n.output.ndjson=e.ndjson)}if(t.doctor&&typeof t.doctor=="object"){let e=t.doctor.autoFix;e&&typeof e=="object"&&(typeof e.onInit=="boolean"&&(n.doctor.autoFix.onInit=e.onInit),Array.isArray(e.permitted)&&(n.doctor.autoFix.permitted=e.permitted.filter(p=>typeof p=="string")))}if(t.dashboard&&typeof t.dashboard=="object"){let e=t.dashboard;(e.theme==="auto"||e.theme==="light"||e.theme==="dark")&&(n.dashboard.theme=e.theme),(e.density==="comfortable"||e.density==="compact")&&(n.dashboard.density=e.density)}if(t.errorRetention&&typeof t.errorRetention=="object"){let e=t.errorRetention;typeof e.maxAgeMs=="number"&&e.maxAgeMs>0&&(n.errorRetention.maxAgeMs=e.maxAgeMs)}if(t.plugins&&typeof t.plugins=="object"){let e=t.plugins;typeof e.dir=="string"&&e.dir.trim()?n.plugins.dir=C(e.dir):e.dir===null&&(n.plugins.dir=null)}return n}function G(){return{local:b.join(process.cwd(),"daimon.config.json"),user:b.join(k.homedir(),".daimon","config.json")}}function N(){let{local:r,user:s}=G();if(w.existsSync(r)){let e=JSON.parse(w.readFileSync(r,"utf8"));return{kind:"loaded",config:T(e,r),path:r}}if(w.existsSync(s)){let e=JSON.parse(w.readFileSync(s,"utf8"));return{kind:"loaded",config:T(e,s),path:s}}let n=[b.resolve(M,"..","daimon.config.example.json"),b.resolve(M,"..","..","daimon.config.example.json")].find(e=>w.existsSync(e));return w.mkdirSync(b.dirname(s),{recursive:!0}),n?w.copyFileSync(n,s):w.writeFileSync(s,JSON.stringify(L(),null,2)+`
2
- `,"utf8"),{kind:"stub-created",path:s}}import I from"node:fs";import P from"node:path";import K from"node:os";import{spawn as Q}from"node:child_process";import{fileURLToPath as X}from"node:url";import V from"node:fs";import _ from"node:path";import{fileURLToPath as W}from"node:url";var $=_.dirname(W(import.meta.url));function z(){let r=[_.resolve($,"..","package.json"),_.resolve($,"..","..","package.json")];for(let s of r)try{return JSON.parse(V.readFileSync(s,"utf8"))}catch{}return{}}var j=z().version||"0.0.0";var Y=P.join(K.homedir(),".daimon"),U=P.join(Y,"daemon.lock");function Z(r){try{return process.kill(r,0),!0}catch(s){return s&&s.code==="EPERM"}}function x(){try{let r=I.readFileSync(U,"utf8"),s=JSON.parse(r);if(!s||typeof s.pid!="number")return null;if(!Z(s.pid)){try{I.unlinkSync(U)}catch{}return null}return s}catch{return null}}function tt(){let r=P.dirname(X(import.meta.url));return P.join(r,"main.js")}async function D(r={}){let s={...process.env};r.port&&(s.DAIMON_PORT=String(r.port)),Q(process.execPath,[tt(),"--headless"],{detached:!0,stdio:"ignore",env:s,windowsHide:!0}).unref();let n=Date.now();for(;Date.now()-n<5e3;){let e=x();if(e&&(!r.port||e.apiPort===r.port))return e;await new Promise(p=>setTimeout(p,100))}throw new Error("daemon failed to start within 5s")}function nt(){if(process.env.DAIMON_PORT){let s=Number(process.env.DAIMON_PORT);if(Number.isFinite(s)&&s>0)return s}let r=x();if(r)return r.apiPort;try{let s=N();if(s.kind==="loaded")return s.config.apiPort}catch{}return 4999}var q=()=>`http://127.0.0.1:${nt()}`,F=!1;async function E(){if(!F&&(F=!0,process.env.DAIMON_NO_SPAWN!=="1"&&!x()))try{let r=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0;await D({port:Number.isFinite(r)&&r>0?r:void 0})}catch{}}async function g(r,s="GET"){await E();try{let t=await fetch(q()+r,{method:s}),n=await t.text();try{return{status:t.status,body:JSON.parse(n)}}catch{return{status:t.status,body:n}}}catch{return{status:0,body:{error:"daimon is not running \u2014 start it with: daimon daemon start --detach"}}}}function m(r){return{content:[{type:"text",text:JSON.stringify(r)}]}}function u(r){return{content:[{type:"text",text:JSON.stringify({error:r})}],isError:!0}}async function ot(){let r=new et({name:"daimon",version:j});r.registerTool("list_apps",{description:"List apps in compact form: name, status, port, health, errCount, lastChangeMs. Use list_apps_full for the verbose v0.4 shape.",inputSchema:{}},async()=>{let e=await g("/api/apps?format=compact");return e.status===0?u(e.body?.error||"unknown"):m(e.body)}),r.registerTool("list_apps_full",{description:"List apps in the verbose v0.4 form (uptimeMs, lastCompileMs, metrics, etc.). Heavier \u2014 prefer list_apps unless you need extra fields.",inputSchema:{}},async()=>{let e=await g("/api/apps?format=full");return e.status===0?u(e.body?.error||"unknown"):m(e.body)});let s=process.cwd(),t=a.string().optional().describe("Workspace cwd for name disambiguation; defaults to the MCP server cwd. Use an explicit value when invoking from a different workspace.");r.registerTool("get_status",{description:"Compact status: name, status, port, url, health, errCount, lastChangeMs, uptime. Use get_status_full for the verbose v0.4 shape.",inputSchema:{name:a.string(),cwd:t}},async({name:e,cwd:p})=>{let c=new URLSearchParams({format:"compact",cwd:p??s}),i=await g(`/api/apps/${encodeURIComponent(e)}?${c.toString()}`);return i.status===0?u(i.body?.error||"unknown"):i.status===412?u(JSON.stringify(i.body)):i.status===404?u("unknown app"):m(i.body)}),r.registerTool("get_status_full",{description:"Verbose v0.4 status form including events, compile history, metrics. Prefer get_status unless you need extra fields.",inputSchema:{name:a.string(),cwd:t}},async({name:e,cwd:p})=>{let c=new URLSearchParams({format:"full",cwd:p??s}),i=await g(`/api/apps/${encodeURIComponent(e)}?${c.toString()}`);return i.status===0?u(i.body?.error||"unknown"):i.status===412?u(JSON.stringify(i.body)):i.status===404?u("unknown app"):m(i.body)}),r.registerTool("get_errors",{description:"Get errors for an app. Supports --since duration, --since-last cursor, optional structured form, and --level (error|warning|lint|all).",inputSchema:{name:a.string(),since:a.string().optional(),sinceLast:a.boolean().optional(),client:a.string().optional(),structured:a.boolean().optional(),level:a.enum(["error","warning","lint","all"]).optional(),cwd:t}},async({name:e,since:p,sinceLast:c,client:i,structured:o,level:l,cwd:f})=>{let S=`/api/apps/${encodeURIComponent(e)}/errors`,h=new URLSearchParams;h.set("cwd",f??s),c?(S+="/since-last",i&&h.set("client",i)):p&&h.set("since",p),l&&h.set("level",l);let y=h.toString(),d=await g(S+(y?"?"+y:""));if(d.status===0)return u(d.body?.error||"unknown");if(d.status===412)return u(JSON.stringify(d.body));if(d.status===404)return u("unknown app");let v=d.body;return o&&Array.isArray(v)&&(v=v.map(R=>R.parsed??{message:R.message})),m(v)}),r.registerTool("get_logs",{description:"Get recent log lines for an app.",inputSchema:{name:a.string(),tail:a.number().int().positive().optional(),since:a.string().optional(),cwd:t}},async({name:e,tail:p,since:c,cwd:i})=>{let o=new URLSearchParams;o.set("cwd",i??s),p&&o.set("tail",String(p)),c&&o.set("since",c);let l=o.toString(),f=await g(`/api/apps/${encodeURIComponent(e)}/logs${l?"?"+l:""}`);return f.status===0?u(f.body?.error||"unknown"):f.status===412?u(JSON.stringify(f.body)):f.status===404?u("unknown app"):m(f.body)});for(let e of["start","stop","restart"])r.registerTool(`${e}_app`,{description:`${e} an app.`,inputSchema:{name:a.string(),cwd:t}},async({name:p,cwd:c})=>{let i=new URLSearchParams({cwd:c??s}),o=await g(`/api/apps/${encodeURIComponent(p)}/${e}?${i.toString()}`,"POST");return o.status===0?u(o.body?.error||"unknown"):o.status===412?u(JSON.stringify(o.body)):m(o.body)});r.registerTool("overview",{description:'Decision-ready snapshot of the workspace: totals, byStatus, needsAttention (with first parsed error per failing app), recentlyChanged. The recommended first call in a session \u2014 answers "what is going on right now?" in one round-trip. Pass `budget` (tokens) to cap response size; overflow collapses to _meta.omitted.',inputSchema:{workspace:a.string().optional(),profile:a.string().optional(),budget:a.number().int().positive().max(5e4).optional()}},async({workspace:e,profile:p,budget:c})=>{let i=new URLSearchParams;e&&i.set("workspace",e),p&&i.set("profile",p),c&&i.set("budget",String(c));let o=i.toString(),l=await g("/api/overview"+(o?"?"+o:""));return l.status===0?u(l.body?.error||"unknown"):m(l.body)}),r.registerTool("diff_errors",{description:'Errors that appeared since the last call by this client. Compact list of {file,line,col,code,message,tool}; bounded by `budget` tokens \u2014 overflow collapses to {omitted:N}. Use this as the "did my last change introduce new errors?" round-trip.',inputSchema:{name:a.string(),client:a.string().optional(),budget:a.number().int().positive().max(5e4).optional()}},async({name:e,client:p,budget:c})=>{let i=new URLSearchParams;i.set("client",p||"mcp-default");let o=await g(`/api/apps/${encodeURIComponent(e)}/errors/since-last?${i.toString()}`);if(o.status===0)return u(o.body?.error||"unknown");if(o.status===404)return u("unknown app");let f=(Array.isArray(o.body)?o.body:[]).map(d=>({file:d.file??null,line:d.line??null,col:d.col??null,code:d.code??null,tool:d.tool??null,message:d.message??""})),S=(c??800)*4,h=0,y=f;for(;JSON.stringify(y).length>S&&y.length>0;)y.pop(),h++;return m({errors:y,_meta:{omitted:h,total:f.length,budget:c??800}})}),r.registerTool("try_fix",{description:"Composite remediation: run doctor --auto-fix for permitted rules, restart the named app, wait for the target state, return {before, after, fixed:[ruleName], stillFailing:[\u2026parsed first 5]}. Never edits user source code, only daemon state. Pair with `focus` for narration; use this for the action.",inputSchema:{name:a.string(),until:a.enum(["serving","healthy"]).optional(),timeoutMs:a.number().int().positive().max(6e5).optional()}},async({name:e,until:p,timeoutMs:c})=>{let i=new URLSearchParams;i.set("until",p||"healthy"),i.set("timeoutMs",String(Math.min(c??18e4,6e5)));let o=await g(`/api/apps/${encodeURIComponent(e)}/try-fix?${i.toString()}`,"POST");return o.status===0?u(o.body?.error||"unknown"):o.status===404?u("unknown app"):m(o.body)}),r.registerTool("focus",{description:'Single round-trip "subscribe-then-act" snapshot for one app: starts the app if stopped, then narrates status/error/health events until target state (serving|healthy|stable) or timeout. Returns the captured event list plus final state. Use as a coherent narrative instead of polling.',inputSchema:{name:a.string(),until:a.enum(["serving","healthy","stable"]).optional(),timeoutMs:a.number().int().positive().max(6e5).optional()}},async({name:e,until:p,timeoutMs:c})=>{let i=new URLSearchParams;i.set("until",p||"healthy"),i.set("timeoutMs",String(Math.min(c??18e4,6e5))),await E();try{let o=await fetch(q()+`/api/apps/${encodeURIComponent(e)}/focus?${i.toString()}`,{method:"POST"});if(o.status===404)return u("unknown app");if(!o.body)return u("no response body");let l=o.body.getReader(),f=new TextDecoder,S=[],h=null,y="";for(;;){let{done:d,value:v}=await l.read();if(d)break;y+=f.decode(v,{stream:!0});let R=y.split(`
3
- `);y=R.pop()??"";for(let J of R){let O=J.trim();if(O)try{let A=JSON.parse(O);A.kind==="done"?h=A:S.push(A)}catch{}}}return m({events:S,final:h})}catch(o){return u(o?.message||String(o))}}),r.registerTool("ensure",{description:'One-call lifecycle: if the app is stopped/crashed/error, start it; then block until it reaches the target state. Idempotent \u2014 returns immediately on already-terminal apps. Replaces the list\u2192status\u2192start\u2192wait\u2192status sequence. Returns compact AppSummary plus _meta.startedFromState / waitedMs. On timeout the body is { error: "timeout", state, _meta: { timedOut: true } } \u2014 treat as exit 2 equivalent.',inputSchema:{name:a.string(),until:a.enum(["serving","healthy"]).optional(),timeoutMs:a.number().int().positive().max(6e5).optional()}},async({name:e,until:p,timeoutMs:c})=>{let i=new URLSearchParams;i.set("until",p||"healthy"),i.set("timeoutMs",String(Math.min(c??18e4,6e5)));let o=await g(`/api/apps/${encodeURIComponent(e)}/ensure?${i.toString()}`,"POST");return o.status===0?u(o.body?.error||"unknown"):o.status===404?u("unknown app"):m(o.body)}),r.registerTool("orchestrate",{description:'Bring up an entire profile in one MCP call: cascade-start every app via depends-order, wait until each reaches the goal, and run ONE round of try-fix on stragglers. Returns { profile, goal, perApp:[{name, reached, tries, fixed?, stillFailing?}], totalMs, allReached }. goal=stable means serving+healthy+5s idle. Honors --budget (drops stillFailing first when over-budget). --dryRun reports planned order + currently-unhealthy apps without starting anything. Recommended way to "bring up my whole workspace" in one call.',inputSchema:{profile:a.string(),goal:a.enum(["serving","healthy","stable"]).optional(),timeoutMs:a.number().int().positive().max(12e5).optional(),dryRun:a.boolean().optional(),budget:a.number().int().positive().optional()}},async({profile:e,goal:p,timeoutMs:c,dryRun:i,budget:o})=>{let l=new URLSearchParams;l.set("profile",e),l.set("goal",p||"healthy"),l.set("timeoutMs",String(Math.min(c??3e5,12e5))),i&&l.set("dryRun","true"),typeof o=="number"&&l.set("budget",String(o));let f=await g(`/api/orchestrate?${l.toString()}`,"POST");return f.status===0?u(f.body?.error||"unknown"):f.status===404?u(f.body?.error||"unknown profile"):m(f.body)}),r.registerTool("ensure_up",{description:"One-call profile bring-up: cascade-start every app in the profile (resolving deps) and block until each reaches the target. Returns per-app terminal state plus _meta.totalMs. Use this instead of daimon up + per-app waits.",inputSchema:{profile:a.string(),until:a.enum(["serving","healthy"]).optional(),timeoutMs:a.number().int().positive().max(12e5).optional()}},async({profile:e,until:p,timeoutMs:c})=>{let i=new URLSearchParams;i.set("until",p||"healthy"),i.set("timeoutMs",String(Math.min(c??3e5,12e5)));let o=await g(`/api/profiles/${encodeURIComponent(e)}/ensure-up?${i.toString()}`,"POST");return o.status===0?u(o.body?.error||"unknown"):o.status===404?u("unknown profile"):m(o.body)}),r.registerTool("wait_for_app",{description:"Block until app reaches the given state or timeout (max 600s).",inputSchema:{name:a.string(),until:a.enum(["serving","healthy","stopped","error"]).optional(),timeout:a.number().int().positive().max(600).optional()}},async({name:e,until:p,timeout:c})=>{let i=new URLSearchParams;i.set("until",p||"serving"),i.set("timeout",String(Math.min(c??120,600)));let o=await g(`/api/apps/${encodeURIComponent(e)}/wait?${i.toString()}`);return o.status===0?u(o.body?.error||"unknown"):o.status===404?u("unknown app"):m(o.body)});let n=new rt;await r.connect(n)}ot().catch(r=>{process.stderr.write(`[daimon-mcp] fatal: ${r?.stack||r}
1
+ import{McpServer as st}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as it}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as p}from"zod";import v from"node:fs";import w from"node:path";import A from"node:os";import{fileURLToPath as H}from"node:url";var V=H(import.meta.url),O=w.dirname(V);function T(){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:w.join(A.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:w.join(A.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]}},dashboard:{theme:"auto",density:"comfortable"},errorRetention:{maxAgeMs:864e5},plugins:{dir:null},webhooks:[]}}function P(n){return n.startsWith("~/")||n.startsWith("~\\")?w.join(A.homedir(),n.slice(2)):n==="~"?A.homedir():n}function j(n,a){if(!n||typeof n!="object")throw new Error(`Config at ${a} is not a JSON object`);let t=n,s=T();if(t.searchRoots!==void 0){if(!Array.isArray(t.searchRoots)||!t.searchRoots.every(e=>typeof e=="string"||e&&typeof e=="object"&&typeof e.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${a})`);s.searchRoots=t.searchRoots}if(t.portRange!==void 0){if(!Array.isArray(t.portRange)||t.portRange.length!==2||typeof t.portRange[0]!="number"||typeof t.portRange[1]!="number"||t.portRange[0]>t.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${a})`);s.portRange=[t.portRange[0],t.portRange[1]]}if(t.apiPort!==void 0){if(typeof t.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${a})`);s.apiPort=t.apiPort}if(t.overrides!==void 0){if(typeof t.overrides!="object"||t.overrides===null||Array.isArray(t.overrides))throw new Error(`Config "overrides" must be an object (${a})`);s.overrides=t.overrides}if(t.autoStart!==void 0){if(!Array.isArray(t.autoStart)||!t.autoStart.every(e=>typeof e=="string"))throw new Error(`Config "autoStart" must be an array of strings (${a})`);s.autoStart=t.autoStart}if(t.profiles!==void 0){if(typeof t.profiles!="object"||t.profiles===null||Array.isArray(t.profiles))throw new Error(`Config "profiles" must be an object (${a})`);for(let[e,c]of Object.entries(t.profiles))if(!Array.isArray(c)||!c.every(i=>typeof i=="string"))throw new Error(`Config "profiles.${e}" must be an array of strings (${a})`);s.profiles=t.profiles}if(t.tags!==void 0){if(typeof t.tags!="object"||t.tags===null||Array.isArray(t.tags))throw new Error(`Config "tags" must be an object (${a})`);s.tags=t.tags}if(t.autoRestart&&typeof t.autoRestart=="object"&&(s.autoRestart={...s.autoRestart,...t.autoRestart}),t.healthProbe&&typeof t.healthProbe=="object"&&(s.healthProbe={...s.healthProbe,...t.healthProbe}),t.logs&&typeof t.logs=="object"&&(s.logs={...s.logs,...t.logs},s.logs.dir=P(s.logs.dir)),t.depends&&typeof t.depends=="object"&&!Array.isArray(t.depends)){for(let[e,c]of Object.entries(t.depends))if(!Array.isArray(c)||!c.every(i=>typeof i=="string"))throw new Error(`Config "depends.${e}" must be an array of strings (${a})`);s.depends=t.depends}if(typeof t.cascadeRestart=="boolean"&&(s.cascadeRestart=t.cascadeRestart),t.history&&typeof t.history=="object"&&(s.history={...s.history,...t.history},s.history.path=P(s.history.path)),t.notifications&&typeof t.notifications=="object"&&(s.notifications={...s.notifications,...t.notifications}),t.staleDetect&&typeof t.staleDetect=="object"&&(s.staleDetect={...s.staleDetect,...t.staleDetect}),typeof t.headless=="boolean"&&(s.headless=t.headless),t.envFiles&&typeof t.envFiles=="object"&&!Array.isArray(t.envFiles)&&(s.envFiles=t.envFiles),t.requestLog&&typeof t.requestLog=="object"&&(s.requestLog={...s.requestLog,...t.requestLog}),t.metrics&&typeof t.metrics=="object"&&(s.metrics={...s.metrics,...t.metrics}),t.editor&&typeof t.editor=="object"){let e=t.editor.scheme;typeof e=="string"&&e.trim()&&(s.editor={scheme:e.trim()})}if((typeof t.apiToken=="string"||t.apiToken===null)&&(s.apiToken=t.apiToken),t.output&&typeof t.output=="object"){let e=t.output;(e.format==="compact"||e.format==="full")&&(s.output.format=e.format),typeof e.ndjson=="boolean"&&(s.output.ndjson=e.ndjson)}if(t.doctor&&typeof t.doctor=="object"){let e=t.doctor.autoFix;e&&typeof e=="object"&&(typeof e.onInit=="boolean"&&(s.doctor.autoFix.onInit=e.onInit),Array.isArray(e.permitted)&&(s.doctor.autoFix.permitted=e.permitted.filter(c=>typeof c=="string")))}if(t.dashboard&&typeof t.dashboard=="object"){let e=t.dashboard;(e.theme==="auto"||e.theme==="light"||e.theme==="dark")&&(s.dashboard.theme=e.theme),(e.density==="comfortable"||e.density==="compact")&&(s.dashboard.density=e.density)}if(t.errorRetention&&typeof t.errorRetention=="object"){let e=t.errorRetention;typeof e.maxAgeMs=="number"&&e.maxAgeMs>0&&(s.errorRetention.maxAgeMs=e.maxAgeMs)}if(t.plugins&&typeof t.plugins=="object"){let e=t.plugins;typeof e.dir=="string"&&e.dir.trim()?s.plugins.dir=P(e.dir):e.dir===null&&(s.plugins.dir=null)}if(Array.isArray(t.webhooks)){let e=[];for(let c of t.webhooks){if(!c||typeof c!="object")continue;let i=c;if(typeof i.url!="string"||!i.url.trim())continue;let r={url:i.url};if(Array.isArray(i.events)&&(r.events=i.events.filter(o=>typeof o=="string")),i.headers&&typeof i.headers=="object"){let o={};for(let[f,u]of Object.entries(i.headers))typeof u=="string"&&(o[f]=u);r.headers=o}if(i.filter&&typeof i.filter=="object"){let o={};for(let f of["to","from","app"])Array.isArray(i.filter[f])&&(o[f]=i.filter[f].filter(u=>typeof u=="string"));r.filter=o}e.push(r)}s.webhooks=e}return s}function z(){return{local:w.join(process.cwd(),"daimon.config.json"),user:w.join(A.homedir(),".daimon","config.json")}}function I(){let{local:n,user:a}=z();if(v.existsSync(n)){let e=JSON.parse(v.readFileSync(n,"utf8"));return{kind:"loaded",config:j(e,n),path:n}}if(v.existsSync(a)){let e=JSON.parse(v.readFileSync(a,"utf8"));return{kind:"loaded",config:j(e,a),path:a}}let s=[w.resolve(O,"..","daimon.config.example.json"),w.resolve(O,"..","..","daimon.config.example.json")].find(e=>v.existsSync(e));return v.mkdirSync(w.dirname(a),{recursive:!0}),s?v.copyFileSync(s,a):v.writeFileSync(a,JSON.stringify(T(),null,2)+`
2
+ `,"utf8"),{kind:"stub-created",path:a}}import $ from"node:fs";import R from"node:path";import X from"node:os";import{spawn as Y}from"node:child_process";import{fileURLToPath as Z}from"node:url";import W from"node:fs";import C from"node:path";import{fileURLToPath as K}from"node:url";var D=C.dirname(K(import.meta.url));function Q(){let n=[C.resolve(D,"..","package.json"),C.resolve(D,"..","..","package.json")];for(let a of n)try{return JSON.parse(W.readFileSync(a,"utf8"))}catch{}return{}}var M=Q().version||"0.0.0";var tt=R.join(X.homedir(),".daimon"),N=R.join(tt,"daemon.lock");function et(n){try{return process.kill(n,0),!0}catch(a){return a&&a.code==="EPERM"}}function x(){try{let n=$.readFileSync(N,"utf8"),a=JSON.parse(n);if(!a||typeof a.pid!="number")return null;if(!et(a.pid)){try{$.unlinkSync(N)}catch{}return null}return a}catch{return null}}function rt(){let n=R.dirname(Z(import.meta.url));return R.join(n,"main.js")}async function U(n={}){let a={...process.env};n.port&&(a.DAIMON_PORT=String(n.port)),Y(process.execPath,[rt(),"--headless"],{detached:!0,stdio:"ignore",env:a,windowsHide:!0}).unref();let s=Date.now();for(;Date.now()-s<5e3;){let e=x();if(e&&(!n.port||e.apiPort===n.port))return e;await new Promise(c=>setTimeout(c,100))}throw new Error("daemon failed to start within 5s")}import nt from"node:os";import ot from"node:crypto";var Ct=5*6e4;function E(){let n=process.env.DAIMON_AGENT_ID;if(n&&n.trim())return n.trim();let a=(nt.hostname()||"unknown").split(".")[0].toLowerCase().replace(/[^a-z0-9-]/g,"").slice(0,24)||"host",t=process.pid,s=ot.randomBytes(2).toString("hex"),e=`${a}-${t}-${s}`;return process.env.DAIMON_AGENT_ID=e,e}var at=E();function F(){return{"x-daimon-agent":at,"x-daimon-cwd":process.cwd()}}function ct(){if(process.env.DAIMON_PORT){let a=Number(process.env.DAIMON_PORT);if(Number.isFinite(a)&&a>0)return a}let n=x();if(n)return n.apiPort;try{let a=I();if(a.kind==="loaded")return a.config.apiPort}catch{}return 4999}var J=()=>`http://127.0.0.1:${ct()}`,q=!1;async function G(){if(!q&&(q=!0,process.env.DAIMON_NO_SPAWN!=="1"&&!x()))try{let n=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0;await U({port:Number.isFinite(n)&&n>0?n:void 0})}catch{}}async function h(n,a="GET"){await G();try{let t=await fetch(J()+n,{method:a,headers:F()}),s=await t.text();try{return{status:t.status,body:JSON.parse(s)}}catch{return{status:t.status,body:s}}}catch{return{status:0,body:{error:"daimon is not running \u2014 start it with: daimon daemon start --detach"}}}}function g(n){return{content:[{type:"text",text:JSON.stringify(n)}]}}function l(n){return{content:[{type:"text",text:JSON.stringify({error:n})}],isError:!0}}async function pt(){let n=new st({name:"daimon",version:M});n.registerTool("list_apps",{description:"List apps in compact form: name, status, port, health, errCount, lastChangeMs. Use list_apps_full for the verbose v0.4 shape.",inputSchema:{}},async()=>{let e=await h("/api/apps?format=compact");return e.status===0?l(e.body?.error||"unknown"):g(e.body)}),n.registerTool("list_apps_full",{description:"List apps in the verbose v0.4 form (uptimeMs, lastCompileMs, metrics, etc.). Heavier \u2014 prefer list_apps unless you need extra fields.",inputSchema:{}},async()=>{let e=await h("/api/apps?format=full");return e.status===0?l(e.body?.error||"unknown"):g(e.body)});let a=process.cwd(),t=p.string().optional().describe("Workspace cwd for name disambiguation; defaults to the MCP server cwd. Use an explicit value when invoking from a different workspace.");n.registerTool("get_status",{description:"Compact status: name, status, port, url, health, errCount, lastChangeMs, uptime. Use get_status_full for the verbose v0.4 shape.",inputSchema:{name:p.string(),cwd:t}},async({name:e,cwd:c})=>{let i=new URLSearchParams({format:"compact",cwd:c??a}),r=await h(`/api/apps/${encodeURIComponent(e)}?${i.toString()}`);return r.status===0?l(r.body?.error||"unknown"):r.status===412?l(JSON.stringify(r.body)):r.status===404?l("unknown app"):g(r.body)}),n.registerTool("get_status_full",{description:"Verbose v0.4 status form including events, compile history, metrics. Prefer get_status unless you need extra fields.",inputSchema:{name:p.string(),cwd:t}},async({name:e,cwd:c})=>{let i=new URLSearchParams({format:"full",cwd:c??a}),r=await h(`/api/apps/${encodeURIComponent(e)}?${i.toString()}`);return r.status===0?l(r.body?.error||"unknown"):r.status===412?l(JSON.stringify(r.body)):r.status===404?l("unknown app"):g(r.body)}),n.registerTool("get_errors",{description:"Get errors for an app. Supports --since duration, --since-last cursor, optional structured form, and --level (error|warning|lint|all).",inputSchema:{name:p.string(),since:p.string().optional(),sinceLast:p.boolean().optional(),client:p.string().optional(),structured:p.boolean().optional(),level:p.enum(["error","warning","lint","all"]).optional(),cwd:t}},async({name:e,since:c,sinceLast:i,client:r,structured:o,level:f,cwd:u})=>{let y=`/api/apps/${encodeURIComponent(e)}/errors`,d=new URLSearchParams;d.set("cwd",u??a),i?(y+="/since-last",r&&d.set("client",r)):c&&d.set("since",c),f&&d.set("level",f);let b=d.toString(),m=await h(y+(b?"?"+b:""));if(m.status===0)return l(m.body?.error||"unknown");if(m.status===412)return l(JSON.stringify(m.body));if(m.status===404)return l("unknown app");let S=m.body;return o&&Array.isArray(S)&&(S=S.map(k=>k.parsed??{message:k.message})),g(S)}),n.registerTool("get_logs",{description:"Get recent log lines for an app.",inputSchema:{name:p.string(),tail:p.number().int().positive().optional(),since:p.string().optional(),cwd:t}},async({name:e,tail:c,since:i,cwd:r})=>{let o=new URLSearchParams;o.set("cwd",r??a),c&&o.set("tail",String(c)),i&&o.set("since",i);let f=o.toString(),u=await h(`/api/apps/${encodeURIComponent(e)}/logs${f?"?"+f:""}`);return u.status===0?l(u.body?.error||"unknown"):u.status===412?l(JSON.stringify(u.body)):u.status===404?l("unknown app"):g(u.body)});for(let e of["start","stop","restart"])n.registerTool(`${e}_app`,{description:`${e} an app.`,inputSchema:{name:p.string(),cwd:t}},async({name:c,cwd:i})=>{let r=new URLSearchParams({cwd:i??a}),o=await h(`/api/apps/${encodeURIComponent(c)}/${e}?${r.toString()}`,"POST");return o.status===0?l(o.body?.error||"unknown"):o.status===412?l(JSON.stringify(o.body)):g(o.body)});n.registerTool("overview",{description:'Decision-ready snapshot of the workspace: totals, byStatus, needsAttention (with first parsed error per failing app), recentlyChanged. The recommended first call in a session \u2014 answers "what is going on right now?" in one round-trip. Pass `budget` (tokens) to cap response size; overflow collapses to _meta.omitted.',inputSchema:{workspace:p.string().optional(),profile:p.string().optional(),budget:p.number().int().positive().max(5e4).optional()}},async({workspace:e,profile:c,budget:i})=>{let r=new URLSearchParams;e&&r.set("workspace",e),c&&r.set("profile",c),i&&r.set("budget",String(i));let o=r.toString(),f=await h("/api/overview"+(o?"?"+o:""));return f.status===0?l(f.body?.error||"unknown"):g(f.body)}),n.registerTool("diff_errors",{description:'Errors that appeared since the last call by this client. Compact list of {file,line,col,code,message,tool}; bounded by `budget` tokens \u2014 overflow collapses to {omitted:N}. Use this as the "did my last change introduce new errors?" round-trip.',inputSchema:{name:p.string(),client:p.string().optional(),budget:p.number().int().positive().max(5e4).optional()}},async({name:e,client:c,budget:i})=>{let r=new URLSearchParams;r.set("client",c||"mcp-default");let o=await h(`/api/apps/${encodeURIComponent(e)}/errors/since-last?${r.toString()}`);if(o.status===0)return l(o.body?.error||"unknown");if(o.status===404)return l("unknown app");let u=(Array.isArray(o.body)?o.body:[]).map(m=>({file:m.file??null,line:m.line??null,col:m.col??null,code:m.code??null,tool:m.tool??null,message:m.message??""})),y=(i??800)*4,d=0,b=u;for(;JSON.stringify(b).length>y&&b.length>0;)b.pop(),d++;return g({errors:b,_meta:{omitted:d,total:u.length,budget:i??800}})}),n.registerTool("try_fix",{description:"Composite remediation: run doctor --auto-fix for permitted rules, restart the named app, wait for the target state, return {before, after, fixed:[ruleName], stillFailing:[\u2026parsed first 5]}. Never edits user source code, only daemon state. Pair with `focus` for narration; use this for the action.",inputSchema:{name:p.string(),until:p.enum(["serving","healthy"]).optional(),timeoutMs:p.number().int().positive().max(6e5).optional()}},async({name:e,until:c,timeoutMs:i})=>{let r=new URLSearchParams;r.set("until",c||"healthy"),r.set("timeoutMs",String(Math.min(i??18e4,6e5)));let o=await h(`/api/apps/${encodeURIComponent(e)}/try-fix?${r.toString()}`,"POST");return o.status===0?l(o.body?.error||"unknown"):o.status===404?l("unknown app"):g(o.body)}),n.registerTool("focus",{description:'Single round-trip "subscribe-then-act" snapshot for one app: starts the app if stopped, then narrates status/error/health events until target state (serving|healthy|stable) or timeout. Returns the captured event list plus final state. Use as a coherent narrative instead of polling.',inputSchema:{name:p.string(),until:p.enum(["serving","healthy","stable"]).optional(),timeoutMs:p.number().int().positive().max(6e5).optional()}},async({name:e,until:c,timeoutMs:i})=>{let r=new URLSearchParams;r.set("until",c||"healthy"),r.set("timeoutMs",String(Math.min(i??18e4,6e5))),await G();try{let o=await fetch(J()+`/api/apps/${encodeURIComponent(e)}/focus?${r.toString()}`,{method:"POST",headers:F()});if(o.status===404)return l("unknown app");if(!o.body)return l("no response body");let f=o.body.getReader(),u=new TextDecoder,y=[],d=null,b="";for(;;){let{done:m,value:S}=await f.read();if(m)break;b+=u.decode(S,{stream:!0});let k=b.split(`
3
+ `);b=k.pop()??"";for(let B of k){let L=B.trim();if(L)try{let _=JSON.parse(L);_.kind==="done"?d=_:y.push(_)}catch{}}}return g({events:y,final:d})}catch(o){return l(o?.message||String(o))}}),n.registerTool("ensure",{description:'One-call lifecycle: if the app is stopped/crashed/error, start it; then block until it reaches the target state. Idempotent \u2014 returns immediately on already-terminal apps. Replaces the list\u2192status\u2192start\u2192wait\u2192status sequence. Returns compact AppSummary plus _meta.startedFromState / waitedMs. On timeout the body is { error: "timeout", state, _meta: { timedOut: true } } \u2014 treat as exit 2 equivalent.',inputSchema:{name:p.string(),until:p.enum(["serving","healthy"]).optional(),timeoutMs:p.number().int().positive().max(6e5).optional()}},async({name:e,until:c,timeoutMs:i})=>{let r=new URLSearchParams;r.set("until",c||"healthy"),r.set("timeoutMs",String(Math.min(i??18e4,6e5)));let o=await h(`/api/apps/${encodeURIComponent(e)}/ensure?${r.toString()}`,"POST");return o.status===0?l(o.body?.error||"unknown"):o.status===404?l("unknown app"):g(o.body)}),n.registerTool("orchestrate",{description:'Bring up an entire profile in one MCP call: cascade-start every app via depends-order, wait until each reaches the goal, and run ONE round of try-fix on stragglers. Returns { profile, goal, perApp:[{name, reached, tries, fixed?, stillFailing?}], totalMs, allReached }. goal=stable means serving+healthy+5s idle. Honors --budget (drops stillFailing first when over-budget). --dryRun reports planned order + currently-unhealthy apps without starting anything. Recommended way to "bring up my whole workspace" in one call.',inputSchema:{profile:p.string(),goal:p.enum(["serving","healthy","stable"]).optional(),timeoutMs:p.number().int().positive().max(12e5).optional(),dryRun:p.boolean().optional(),budget:p.number().int().positive().optional()}},async({profile:e,goal:c,timeoutMs:i,dryRun:r,budget:o})=>{let f=new URLSearchParams;f.set("profile",e),f.set("goal",c||"healthy"),f.set("timeoutMs",String(Math.min(i??3e5,12e5))),r&&f.set("dryRun","true"),typeof o=="number"&&f.set("budget",String(o));let u=await h(`/api/orchestrate?${f.toString()}`,"POST");return u.status===0?l(u.body?.error||"unknown"):u.status===404?l(u.body?.error||"unknown profile"):g(u.body)}),n.registerTool("ensure_up",{description:"One-call profile bring-up: cascade-start every app in the profile (resolving deps) and block until each reaches the target. Returns per-app terminal state plus _meta.totalMs. Use this instead of daimon up + per-app waits.",inputSchema:{profile:p.string(),until:p.enum(["serving","healthy"]).optional(),timeoutMs:p.number().int().positive().max(12e5).optional()}},async({profile:e,until:c,timeoutMs:i})=>{let r=new URLSearchParams;r.set("until",c||"healthy"),r.set("timeoutMs",String(Math.min(i??3e5,12e5)));let o=await h(`/api/profiles/${encodeURIComponent(e)}/ensure-up?${r.toString()}`,"POST");return o.status===0?l(o.body?.error||"unknown"):o.status===404?l("unknown profile"):g(o.body)}),n.registerTool("wait_for_app",{description:"Block until app reaches the given state or timeout (max 600s).",inputSchema:{name:p.string(),until:p.enum(["serving","healthy","stopped","error"]).optional(),timeout:p.number().int().positive().max(600).optional()}},async({name:e,until:c,timeout:i})=>{let r=new URLSearchParams;r.set("until",c||"serving"),r.set("timeout",String(Math.min(i??120,600)));let o=await h(`/api/apps/${encodeURIComponent(e)}/wait?${r.toString()}`);return o.status===0?l(o.body?.error||"unknown"):o.status===404?l("unknown app"):g(o.body)}),n.registerTool("daimon_who_owns",{description:"Return the current soft-lock holder for an app (if any) and the last 3 agents who interacted with it. Use before start/stop/restart to avoid stepping on another agent.",inputSchema:{name:p.string(),cwd:t}},async({name:e,cwd:c})=>{let i=new URLSearchParams({cwd:c??a}),r=await h(`/api/apps/${encodeURIComponent(e)}/lock?${i.toString()}`);return r.status===0?l(r.body?.error||"unknown"):r.status===404?l("unknown app"):g(r.body)}),n.registerTool("daimon_subscribe_events",{description:"Long-poll for new daimon events. Returns events newer than `sinceMs` (default 60s) for `app` (or all apps), filtered by `kinds` (status, error, warning, lint, health, restart, bundle, task). Use to react to errors / status changes without sleeping.",inputSchema:{app:p.string().optional(),kinds:p.array(p.string()).optional(),sinceMs:p.number().int().positive().max(864e5).optional()}},async({app:e,kinds:c,sinceMs:i})=>{let r=new URLSearchParams;r.set("since",String(i??6e4)+"ms"),e&&r.set("app",e);let o=await h(`/api/events?${r.toString()}`);if(o.status===0)return l(o.body?.error||"unknown");let f=Array.isArray(o.body)?o.body:[];if(c&&c.length){let u=new Set(c);f=f.filter(y=>{let d=y.type??"";return!!(d==="status"&&u.has("status")||(d==="error-new"||d==="error-recur")&&u.has("error")||(d==="warning-new"||d==="warning-recur")&&u.has("warning")||(d==="lint-new"||d==="lint-recur")&&u.has("lint")||d==="health"&&u.has("health")||(d==="restart-scheduled"||d==="compile-regression"||d==="bundle-regression")&&u.has("restart")||d==="bundle"&&u.has("bundle")||d==="task-run"&&u.has("task")||d==="regression-detected"&&u.has("regression"))})}return g(f)}),n.registerTool("daimon_notify_on_error",{description:'Block (up to `timeoutMs`) until the next error-new event for `app`. Convenience wrapper around daimon_subscribe_events for the common "tell me when this app errors" pattern. Returns { error, ts } on hit, { timedOut: true } on timeout.',inputSchema:{app:p.string(),timeoutMs:p.number().int().positive().max(6e5).optional()}},async({app:e,timeoutMs:c})=>{let i=Math.min(c??6e4,6e5),r=Date.now(),o=1500;for(;Date.now()-r<i;){let f=Math.max(500,Date.now()-r),u=new URLSearchParams({since:f+"ms",app:e}),y=await h(`/api/events?${u.toString()}`);if(y.status===0)return l(y.body?.error||"unknown");let b=(Array.isArray(y.body)?y.body:[]).find(m=>m.type==="error-new");if(b)return g({error:b,waitedMs:Date.now()-r});await new Promise(m=>setTimeout(m,o))}return g({timedOut:!0,waitedMs:Date.now()-r})});let s=new it;await n.connect(s)}pt().catch(n=>{process.stderr.write(`[daimon-mcp] fatal: ${n?.stack||n}
4
4
  `),process.exit(1)});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "daimon",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Local dev-server manager for Angular/Nx/Vite/Storybook — TUI, loopback HTTP API, JSON CLI, and MCP server for Claude Code",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Yosi Azulay (https://flycotech.com)",
@@ -41,10 +41,12 @@
41
41
  "start": "npm run build && node dist/main.js",
42
42
  "cli": "node dist/cli.js",
43
43
  "mcp": "node dist/mcp.js",
44
- "test": "node --test test/depends.test.mjs test/bundle.test.mjs test/notifier.test.mjs test/regression.test.mjs test/parser-corpus.test.mjs test/overview-budget.test.mjs test/autofix-rules.test.mjs test/history-trends.test.mjs test/orchestrate.test.mjs test/polyglot-discovery.test.mjs test/tui-ribbon.test.mjs test/cli-surface.test.mjs test/parser-fuzz.test.mjs test/history-stress.test.mjs test/lock-contention.test.mjs test/reliability.test.mjs test/self-metrics.test.mjs test/plugins.test.mjs test/task-summary.test.mjs test/path-scope.test.mjs test/health-profiles.test.mjs test/timeline.test.mjs",
44
+ "test": "node --test test/depends.test.mjs test/bundle.test.mjs test/notifier.test.mjs test/regression.test.mjs test/parser-corpus.test.mjs test/overview-budget.test.mjs test/autofix-rules.test.mjs test/history-trends.test.mjs test/orchestrate.test.mjs test/polyglot-discovery.test.mjs test/tui-ribbon.test.mjs test/cli-surface.test.mjs test/parser-fuzz.test.mjs test/history-stress.test.mjs test/lock-contention.test.mjs test/reliability.test.mjs test/self-metrics.test.mjs test/plugins.test.mjs test/task-summary.test.mjs test/path-scope.test.mjs test/health-profiles.test.mjs test/timeline.test.mjs test/agents.test.mjs test/audit.test.mjs test/regressions.test.mjs test/webhooks.test.mjs test/recovery.test.mjs test/perf-50apps.test.mjs test/history-property.test.mjs test/scope-property.test.mjs test/mcp-contract.test.mjs test/profiles.test.mjs",
45
45
  "clean:dist": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
46
46
  "build:bundle": "npm run clean:dist && esbuild src/cli.ts src/main.ts src/mcp.ts --bundle --platform=node --target=node20 --format=esm --minify --legal-comments=none --outdir=dist --packages=external",
47
47
  "build:dashboard": "node -e \"const fs=require('fs');if(fs.existsSync('dashboard/node_modules')){require('child_process').execSync('npm run build',{cwd:'dashboard',stdio:'inherit'});}else{console.log('[daimon] dashboard/node_modules missing — skipping ng build. Run: (cd dashboard && npm install) to enable the Angular SPA bundle.');}\"",
48
+ "build:vscode": "node -e \"const fs=require('fs');if(fs.existsSync('vscode-extension/node_modules')){require('child_process').execSync('npm run package',{cwd:'vscode-extension',stdio:'inherit'});}else{console.log('[daimon] vscode-extension/node_modules missing — run: (cd vscode-extension && npm install) to enable the VS Code extension build.');}\"",
49
+ "build:docs": "node scripts/build-docs.mjs",
48
50
  "prepublishOnly": "npm run build && npm test && npm run build:bundle && npm run build:dashboard",
49
51
  "dev:install": "node scripts/dev-install.mjs",
50
52
  "dev:install:fast": "node scripts/dev-install.mjs --no-dashboard",
@@ -1 +0,0 @@
1
- import{a as Q}from"./chunk-WRX32YWH.js";import{a as J,b as B,c as H,d as V,e as q}from"./chunk-BBTQXZIS.js";import{g as G}from"./chunk-RNUJZTKS.js";import"./chunk-KRC72WWY.js";import{b as N,d as z}from"./chunk-LBWOIG7N.js";import"./chunk-AGN2F6JP.js";import"./chunk-SR4HVFOB.js";import{b as L,c as U,d as K}from"./chunk-WOMCRDMJ.js";import"./chunk-YNQPX5G6.js";import"./chunk-VMW35ZNT.js";import"./chunk-FRKUCFVI.js";import"./chunk-B2DPS6BL.js";import{e as D,f as A}from"./chunk-UC7AWK4C.js";import{a as I,d as j}from"./chunk-X4RGWMLE.js";import"./chunk-JWXROQJJ.js";import{h as R}from"./chunk-EBGPIJ7S.js";import{Db as v,Eb as c,Fb as p,Ib as g,Jb as _,Kb as k,Lb as r,Mb as a,Nb as u,Ub as E,Wa as O,Wb as m,_a as o,ea as h,ic as s,jc as x,kc as P,lc as F,pb as $,s as w,ta as b}from"./chunk-O76B43BY.js";function M(n){if(!n)return null;try{return JSON.parse(n)}catch{return null}}function W(n,e){return`vscode://file/${encodeURI(n.replace(/\\/g,"/"))}${typeof e=="number"?`:${e}`:""}`}function X(n,e){if(!e)return n?`exit ${n.exit_code??"?"}`:"no runs";let t=e.total??(e.passed??0)+(e.failed??0);return`${e.passed??0}/${t}${(e.failed??0)>0?` \xB7 ${e.failed} failed`:""}`}function Y(n,e){return n?(e?.failed??0)>0||n.exit_code!==0?"fail":"ok":"neutral"}var te=(n,e)=>e.app,ne=(n,e)=>e.ts,ae=(n,e)=>e.name+(e.file??"");function ie(n,e){n&1&&u(0,"dm-skeleton",3)}function re(n,e){n&1&&u(0,"dm-empty",4)}function oe(n,e){if(n&1&&u(0,"span",12),n&2){let t=e.$implicit,i=m(3);v("data-kind",t.failed>0?"fail":"pass")("title",i.trendLabel(t))}}function se(n,e){if(n&1&&(r(0,"a",17)(1,"dm-mono"),s(2),a(),r(3,"mat-icon",18),s(4,"launch"),a()()),n&2){let t=m().$implicit,i=m(4);k("href",i.vscodeJump(t.file,t.line),O),o(2),F("",t.file,"",t.line?":"+t.line:"")}}function le(n,e){if(n&1&&(r(0,"li")(1,"span",16),s(2),a(),c(3,se,5,3,"a",17),a()),n&2){let t=e.$implicit;o(2),x(t.name),o(),p(t.file?3:-1)}}function me(n,e){if(n&1&&(r(0,"h4",14),s(1,"Failed tests"),a(),r(2,"ul",15),g(3,le,4,2,"li",null,ae),a()),n&2){let t=m().$implicit;o(3),_(t.latestSummary.failedTests)}}function de(n,e){n&1&&(r(0,"div",13),s(1,"No failed tests in the most recent run."),a())}function ce(n,e){if(n&1&&(r(0,"div",13),s(1),a()),n&2){let t=m().$implicit;o(),P("The task exited with code ",t.latest.exit_code," but no structured failures were parsed \u2014 check raw logs.")}}function pe(n,e){if(n&1&&(r(0,"mat-expansion-panel",6)(1,"mat-expansion-panel-header")(2,"mat-panel-title")(3,"span",7),u(4,"span",8),s(5),a(),r(6,"dm-mono",9),s(7),a()(),r(8,"mat-panel-description")(9,"span",10),s(10),a()()(),r(11,"div",11),g(12,oe,1,2,"span",12,ne),a(),c(14,me,5,0),c(15,de,2,0,"div",13),c(16,ce,2,1,"div",13),a()),n&2){let t=e.$implicit,i=m(2);k("expanded",!1),o(3),v("data-kind",i.pillKindFor(t)),o(2),P("",i.summaryFor(t)," "),o(2),x(t.app),o(3),x(i.subtitleFor(t)),o(2),_(t.trend),o(2),p(t.latest&&(!(t.latestSummary==null||t.latestSummary.failedTests==null)&&t.latestSummary.failedTests.length)?14:-1),o(),p(t.latest&&!(!(t.latestSummary==null||t.latestSummary.failedTests==null)&&t.latestSummary.failedTests.length)&&t.latest.exit_code===0?15:-1),o(),p(t.latest&&t.latest.exit_code!==null&&t.latest.exit_code!==0&&!(!(t.latestSummary==null||t.latestSummary.failedTests==null)&&t.latestSummary.failedTests.length)?16:-1)}}function ue(n,e){if(n&1&&(r(0,"div",5),g(1,pe,17,8,"mat-expansion-panel",6,te),a()),n&2){let t=m();o(),_(t.cards())}}var Z=class n{api=h(j);http=h(I);loading=b(!0);cards=b([]);pillKindFor(e){return Y(e.latest,e.latestSummary)}summaryFor(e){return X(e.latest,e.latestSummary)}subtitleFor(e){if(!e.latest)return"";let t=e.latestSummary?.framework??"unknown",i=e.latest.duration_ms!=null?` \xB7 ${(e.latest.duration_ms/1e3).toFixed(1)}s`:"",d=Math.max(0,Math.round((Date.now()-e.latest.ts)/6e4));return`${t}${i} \xB7 ${d}m ago \xB7 ${e.runs.length} runs in last 30d`}trendLabel(e){return`${new Date(e.ts).toLocaleString()} \u2014 ${e.passed} passed${e.failed>0?", "+e.failed+" failed":""}`}vscodeJump(e,t){return W(e,t)}async ngOnInit(){await this.refresh()}async refresh(){this.loading.set(!0);try{await this.api.refresh();let e=this.api.apps().map(d=>d.name),t=[],i=Date.now()-720*3600*1e3;for(let d of e){let S=await this.fetchTaskRuns(d,i);if(!S.length)continue;let T=S.filter(l=>/test/i.test(l.task));if(!T.length)continue;let y=[...T].sort((l,f)=>f.ts-l.ts),C=y[0]??null,ee=y.slice(0,30).reverse().map(l=>{let f=M(l.summary);return{ts:l.ts,passed:f?.passed??(l.exit_code===0?1:0),failed:f?.failed??(l.exit_code===0?0:1)}});t.push({app:d,runs:y,latest:C,latestSummary:C?M(C.summary):null,trend:ee})}this.cards.set(t)}finally{this.loading.set(!1)}}async fetchTaskRuns(e,t){try{let i=await w(this.http.get(`/api/history/tasks?app=${encodeURIComponent(e)}&since=${Math.round((Date.now()-t)/1e3)}s&limit=200`));return Array.isArray(i)?i:[]}catch{return[]}}static \u0275fac=function(t){return new(t||n)};static \u0275cmp=$({type:n,selectors:[["dm-tests-page"]],decls:15,vars:1,consts:[[1,"dm-page-header"],[1,"dm-page-sub"],["mat-icon-button","","aria-label","Refresh",3,"click"],["height","14rem"],["icon","science","title","No test runs recorded yet","hint","Run daimon run NAME test (or any task whose name contains 'test') to populate this page."],[1,"dm-grid"],[1,"dm-card",3,"expanded"],[1,"dm-pill"],[1,"dm-dot"],[1,"dm-app"],[1,"dm-sub"],["aria-label","Recent pass/fail history",1,"dm-trend-row"],[1,"dm-tick"],[1,"dm-muted"],[1,"dm-h4"],[1,"dm-fail-list"],[1,"dm-fail-name"],["target","_blank","rel","noopener",1,"dm-fail-jump",3,"href"],[1,"dm-jump-icon"]],template:function(t,i){t&1&&(r(0,"div",0)(1,"div")(2,"h1"),s(3,"Tests"),a(),r(4,"div",1),s(5,"Pass/fail trends per app from "),r(6,"dm-mono"),s(7,"task_runs"),a(),s(8," (last 30d). Click a card to inspect the most recent run."),a()(),r(9,"button",2),E("click",function(){return i.refresh()}),r(10,"mat-icon"),s(11,"refresh"),a()()(),c(12,ie,1,0,"dm-skeleton",3)(13,re,1,0,"dm-empty",4)(14,ue,3,0,"div",5)),t&2&&(o(12),p(i.loading()?12:i.cards().length===0?13:14))},dependencies:[R,G,z,N,A,D,q,J,B,V,H,Q,U,L,K],styles:["[_nghost-%COMP%]{display:block;max-width:1200px;margin:0 auto}.dm-page-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap;margin-bottom:1rem}.dm-page-sub[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-size:.875rem}.dm-grid[_ngcontent-%COMP%]{display:grid;gap:.75rem}.dm-card[_ngcontent-%COMP%]{background:var(--mat-sys-surface-container-low)}.dm-app[_ngcontent-%COMP%]{margin-left:.75rem}.dm-sub[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-size:.8125rem}.dm-pill[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:.4rem;padding:2px 10px;border-radius:999px;border:1px solid var(--mat-sys-outline-variant);background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface);font:500 .75rem/1rem Roboto}.dm-pill[_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:999px;background:var(--mat-sys-outline)}.dm-pill[data-kind=ok][_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-primary) 12%,transparent);border-color:color-mix(in oklch,var(--mat-sys-primary) 28%,transparent)}.dm-pill[data-kind=ok][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{background:var(--mat-sys-primary)}.dm-pill[data-kind=fail][_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-error) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-error) 30%,transparent);color:var(--mat-sys-error)}.dm-pill[data-kind=fail][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{background:var(--mat-sys-error)}.dm-trend-row[_ngcontent-%COMP%]{display:flex;gap:2px;margin:.5rem 0}.dm-tick[_ngcontent-%COMP%]{width:6px;height:16px;border-radius:2px;background:var(--mat-sys-outline-variant)}.dm-tick[data-kind=pass][_ngcontent-%COMP%]{background:var(--mat-sys-primary)}.dm-tick[data-kind=fail][_ngcontent-%COMP%]{background:var(--mat-sys-error)}.dm-h4[_ngcontent-%COMP%]{margin:.75rem 0 .35rem;font:500 .8125rem/1rem Roboto;color:var(--mat-sys-on-surface-variant)}.dm-fail-list[_ngcontent-%COMP%]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.35rem}.dm-fail-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{padding:.35rem .6rem;border-radius:6px;background:var(--mat-sys-surface-container);display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap}.dm-fail-name[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface);font-size:.875rem;overflow-wrap:anywhere}.dm-fail-jump[_ngcontent-%COMP%]{color:var(--mat-sys-primary);text-decoration:none;display:inline-flex;align-items:center;gap:.35rem;font-size:.8125rem}.dm-fail-jump[_ngcontent-%COMP%]:hover{text-decoration:underline}.dm-jump-icon[_ngcontent-%COMP%]{font-size:14px;width:14px;height:14px}.dm-muted[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-size:.875rem}"],changeDetection:0})};export{Z as TestsPageComponent};
@@ -1 +0,0 @@
1
- import{a as A,b as $,c as j,f as L,g as z}from"./chunk-RNUJZTKS.js";import{a as I}from"./chunk-7LKM244H.js";import{c as D,d as T}from"./chunk-LBWOIG7N.js";import"./chunk-AGN2F6JP.js";import"./chunk-SR4HVFOB.js";import{b as N,d as R}from"./chunk-WOMCRDMJ.js";import"./chunk-YNQPX5G6.js";import"./chunk-6MTVWBQQ.js";import"./chunk-TGSV7ZHM.js";import"./chunk-VMW35ZNT.js";import"./chunk-FRKUCFVI.js";import"./chunk-B2DPS6BL.js";import{e as E,f as w}from"./chunk-UC7AWK4C.js";import{a as k}from"./chunk-X4RGWMLE.js";import"./chunk-JWXROQJJ.js";import"./chunk-EBGPIJ7S.js";import{Eb as m,Fb as l,Kb as y,Lb as t,Mb as e,Nb as g,Sb as S,Ub as b,Wb as c,_a as r,ea as C,gc as M,ic as i,ja as _,jc as f,ka as h,kc as v,lc as P,pb as x,s as u,ta as d,yc as O}from"./chunk-O76B43BY.js";function V(a,o){a&1&&g(0,"dm-skeleton",2)}function F(a,o){if(a&1&&(t(0,"span"),i(1),e()),a&2){let n=c();r(),v("Recording in progress \xB7 ",n.elapsedLabel())}}function H(a,o){a&1&&(t(0,"span"),i(1,"Not recording"),e())}function J(a,o){a&1&&(t(0,"div",3),g(1,"dm-skeleton",4)(2,"dm-skeleton",4)(3,"dm-skeleton",4),e())}function W(a,o){a&1&&(g(0,"span",20),t(1,"span",21),i(2,"REC"),e())}function q(a,o){a&1&&(t(0,"span",8),i(1,"Idle"),e())}function G(a,o){if(a&1&&(t(0,"div",22)(1,"span",23),i(2,"Path"),e(),t(3,"dm-mono")(4,"span",25),i(5),e()()()),a&2){let n=c(3);r(5),f(n.path())}}function K(a,o){if(a&1&&(t(0,"div",10)(1,"div",22)(2,"span",23),i(3,"Elapsed"),e(),t(4,"dm-mono")(5,"span",24),i(6),e()()(),m(7,G,6,1,"div",22),e()),a&2){let n=c(2);r(6),f(n.elapsedLabel()),r(),l(n.path()?7:-1)}}function Q(a,o){if(a&1){let n=S();t(0,"mat-card",5)(1,"mat-card-content")(2,"div",6)(3,"div",7),m(4,W,3,0)(5,q,2,0,"span",8),e(),t(6,"button",9),b("click",function(){_(n);let p=c();return h(p.toggle())}),t(7,"mat-icon"),i(8),e(),i(9),e()(),m(10,K,8,2,"div",10),e()(),t(11,"div",11)(12,"mat-card",12)(13,"mat-card-header")(14,"mat-card-title"),i(15,"What gets recorded"),e()(),t(16,"mat-card-content")(17,"ul",13)(18,"li"),i(19,"App lifecycle events (start, stop, restart)"),e(),t(20,"li"),i(21,"Task invocations"),e(),t(22,"li"),i(23,"Config changes"),e()(),t(24,"div",14)(25,"span",15),i(26,"Saved as"),e(),t(27,"dm-mono")(28,"span",16),i(29,"~/.daimon/sessions/session-<timestamp>.jsonl"),e()()(),t(30,"div",14)(31,"span",15),i(32,"Replay"),e(),t(33,"dm-mono")(34,"span",16),i(35,"daimon replay session.jsonl --speed 1"),e()()(),t(36,"div",17),i(37," Each JSONL line is "),t(38,"dm-mono")(39,"span",16),i(40),e()(),i(41,". "),e()()(),t(42,"mat-card",12)(43,"mat-card-header")(44,"mat-card-title"),i(45,"Replay primer"),e()(),t(46,"mat-card-content")(47,"div",18)(48,"dm-mono")(49,"span",16),i(50,"daimon replay <file.jsonl>"),e()(),t(51,"span",19),i(52,"play at default speed"),e()(),t(53,"div",18)(54,"dm-mono")(55,"span",16),i(56,"daimon replay <file.jsonl> --speed 2"),e()(),t(57,"span",19),i(58,"2x faster"),e()(),t(59,"div",17),i(60," Replay runs from the CLI. The dashboard doesn't trigger replays. "),e()()()()}if(a&2){let n=c();r(3),M("dm-state-rec",n.recording()),r(),l(n.recording()?4:5),r(2),y("disabled",n.busy()),r(2),f(n.recording()?"stop_circle":"radio_button_checked"),r(),v(" ",n.recording()?"Stop recording":"Start recording"," "),r(),l(n.recording()?10:-1),r(30),P("","{"," ts, kind, app?, task?, args? ","}")}}function U(a){let o=Math.max(0,Math.floor(a/1e3)),n=Math.floor(o/3600),s=Math.floor(o%3600/60),p=o%60;return n>0?`${n}h ${s}m ${p}s`:s>0?`${s}m ${p}s`:`${p}s`}var B=class a{http=C(k);snack=C(I);loading=d(!0);recording=d(!1);path=d(void 0);busy=d(!1);startedAt=d(null);tick=d(0);elapsedLabel=O(()=>{this.tick();let o=this.startedAt();return o?U(Date.now()-o):"0s"});tickTimer;ngOnInit(){this.loadStatus(),this.tickTimer=setInterval(()=>{this.recording()&&this.tick.update(o=>o+1)},1e3)}ngOnDestroy(){this.tickTimer&&clearInterval(this.tickTimer)}async loadStatus(){this.loading.set(!0);try{let o=await u(this.http.get("/api/session/status"));this.recording.set(!!o?.recording),this.path.set(o?.path),o?.recording?this.startedAt.set(Date.now()):this.startedAt.set(null)}catch{this.recording.set(!1),this.startedAt.set(null)}finally{this.loading.set(!1)}}async toggle(){if(this.busy())return;this.busy.set(!0);let o=this.recording();try{let n=await u(this.http.post("/api/session/record?action=toggle",{})),s=!!n?.recording;this.recording.set(s),this.path.set(n?.path),s&&!o?(this.startedAt.set(Date.now()),this.snack.open(n?.path?`Started session at ${n.path}`:"Started session","",{duration:2500})):!s&&o&&(this.startedAt.set(null),this.snack.open("Stopped session","",{duration:2500}))}catch(n){this.snack.open(`Session toggle failed: ${n?.message??"error"}`,"Dismiss",{duration:4e3,panelClass:"dm-snack-error"})}finally{this.busy.set(!1)}}static \u0275fac=function(n){return new(n||a)};static \u0275cmp=x({type:a,selectors:[["dm-sessions-page"]],decls:10,vars:2,consts:[[1,"dm-page-header"],[1,"dm-page-sub"],["width","12rem","height","1rem"],[1,"dm-skel-grid"],["height","9rem"],[1,"dm-status-card"],[1,"dm-status-row"],[1,"dm-state"],[1,"dm-idle-label"],["mat-flat-button","","color","primary",1,"dm-toggle-btn",3,"click","disabled"],[1,"dm-rec-meta"],[1,"dm-info-grid"],[1,"dm-info-card"],[1,"dm-info-list"],[1,"dm-info-row"],[1,"dm-info-label"],[1,"dm-info-mono"],[1,"dm-info-hint"],[1,"dm-replay-row"],[1,"dm-replay-desc"],[1,"dm-rec-dot"],[1,"dm-rec-label"],[1,"dm-meta-row"],[1,"dm-meta-label"],[1,"dm-meta-value"],[1,"dm-meta-value","dm-path"]],template:function(n,s){n&1&&(t(0,"div",0)(1,"div")(2,"h1"),i(3,"Sessions"),e(),t(4,"div",1),m(5,V,1,0,"dm-skeleton",2)(6,F,2,1,"span")(7,H,2,0,"span"),e()()(),m(8,J,4,0,"div",3)(9,Q,61,9)),n&2&&(r(5),l(s.loading()?5:s.recording()?6:7),r(3),l(s.loading()?8:9))},dependencies:[z,A,j,L,$,T,D,w,E,N,R],styles:["[_nghost-%COMP%]{display:block}.dm-page-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]{margin:0}.dm-page-sub[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);margin-top:.25rem;font-size:.875rem}.dm-skel-grid[_ngcontent-%COMP%]{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(18rem,1fr))}.dm-status-card[_ngcontent-%COMP%]{margin-bottom:1rem;border:1px solid var(--mat-sys-outline-variant)}.dm-status-row[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;flex-wrap:wrap}.dm-state[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:.65rem;font:500 1.5rem/2rem Roboto;color:var(--mat-sys-on-surface-variant)}.dm-state-rec[_ngcontent-%COMP%]{color:var(--mat-sys-error)}.dm-rec-dot[_ngcontent-%COMP%]{width:14px;height:14px;border-radius:999px;background:var(--mat-sys-error);box-shadow:0 0 0 4px color-mix(in oklch,var(--mat-sys-error) 22%,transparent);animation:_ngcontent-%COMP%_dm-pulse 1.4s ease-in-out infinite}@keyframes _ngcontent-%COMP%_dm-pulse{0%,to{opacity:1}50%{opacity:.35}}@media(prefers-reduced-motion:reduce){.dm-rec-dot[_ngcontent-%COMP%]{animation:none}}.dm-rec-label[_ngcontent-%COMP%]{letter-spacing:.05rem}.dm-idle-label[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant)}.dm-toggle-btn[_ngcontent-%COMP%]{min-height:48px;padding:0 1.25rem;font-size:1rem}.dm-rec-meta[_ngcontent-%COMP%]{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--mat-sys-outline-variant);display:flex;flex-direction:column;gap:.5rem}.dm-meta-row[_ngcontent-%COMP%]{display:flex;align-items:baseline;gap:.75rem}.dm-meta-label[_ngcontent-%COMP%]{font:500 .6875rem/1rem Roboto;text-transform:uppercase;letter-spacing:.04rem;color:var(--mat-sys-on-surface-variant);min-width:4.5rem}.dm-meta-value[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface)}.dm-path[_ngcontent-%COMP%]{word-break:break-all}.dm-info-grid[_ngcontent-%COMP%]{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr))}.dm-info-card[_ngcontent-%COMP%]{border:1px solid var(--mat-sys-outline-variant)}.dm-info-list[_ngcontent-%COMP%]{margin:0 0 1rem;padding-left:1.25rem;color:var(--mat-sys-on-surface);font-size:.875rem}.dm-info-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{margin-bottom:.25rem}.dm-info-row[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:.15rem;margin-bottom:.65rem}.dm-info-label[_ngcontent-%COMP%]{font:500 .6875rem/1rem Roboto;text-transform:uppercase;letter-spacing:.04rem;color:var(--mat-sys-on-surface-variant)}.dm-info-mono[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface);word-break:break-all}.dm-info-hint[_ngcontent-%COMP%]{margin-top:.5rem;font-size:.8125rem;color:var(--mat-sys-on-surface-variant)}.dm-replay-row[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:.15rem;margin-bottom:.65rem}.dm-replay-desc[_ngcontent-%COMP%]{font-size:.8125rem;color:var(--mat-sys-on-surface-variant)}"],changeDetection:0})};export{B as SessionsPageComponent};
@@ -1 +0,0 @@
1
- import{a as te}from"./chunk-WRX32YWH.js";import{a as U,b as G,c as J,d as X,e as Y,f as Z,g as ee}from"./chunk-RNUJZTKS.js";import{a as j,b as K}from"./chunk-3EPFSBJ2.js";import{a as L,b as q}from"./chunk-7LKM244H.js";import{b as z,c as B,d as V}from"./chunk-LBWOIG7N.js";import"./chunk-AGN2F6JP.js";import"./chunk-SR4HVFOB.js";import{b as H,c as Q,d as W}from"./chunk-WOMCRDMJ.js";import"./chunk-YNQPX5G6.js";import"./chunk-6MTVWBQQ.js";import"./chunk-TGSV7ZHM.js";import"./chunk-VMW35ZNT.js";import"./chunk-FRKUCFVI.js";import"./chunk-B2DPS6BL.js";import{c as I}from"./chunk-PRLUGTKR.js";import{e as R,f as N}from"./chunk-UC7AWK4C.js";import{a as F,d as $}from"./chunk-X4RGWMLE.js";import"./chunk-JWXROQJJ.js";import"./chunk-EBGPIJ7S.js";import{Db as k,Eb as g,Fb as f,Hb as O,Ib as C,Jb as h,Kb as y,Lb as o,Mb as i,Nb as v,Sb as T,Ub as b,Wb as c,_a as d,ea as M,ic as r,ja as E,jc as m,ka as D,kc as P,pb as A,s as w,ta as _,yc as S}from"./chunk-O76B43BY.js";var ie=(n,t)=>t.name,ae=(n,t)=>t.reason,re=(n,t)=>t.id;function de(n,t){n&1&&(o(0,"div",7),v(1,"dm-skeleton",24)(2,"dm-skeleton",25)(3,"dm-skeleton",26),i())}function le(n,t){if(n&1&&(o(0,"div",27)(1,"span",28),r(2,"Connection"),i(),o(3,"span",29)(4,"span",30),v(5,"span",31),r(6),i()()(),o(7,"div",27)(8,"span",28),r(9,"Version"),i(),o(10,"span",29)(11,"dm-mono"),r(12),i()()(),o(13,"div",27)(14,"span",28),r(15,"API port"),i(),o(16,"span",29)(17,"dm-mono"),r(18),i()()(),o(19,"div",27)(20,"span",28),r(21,"Apps tracked"),i(),o(22,"span",29)(23,"dm-mono"),r(24),i()()()),n&2){let e=c();d(4),k("data-kind",e.api.connected()?"ok":"err"),d(2),P("",e.api.connected()?"connected":"disconnected"," "),d(6),m(e.daemonVersion()||"unknown"),d(6),m(e.daemonPort()||"-"),d(6),m(e.api.apps().length)}}function se(n,t){n&1&&(o(0,"div",7),v(1,"dm-skeleton",32)(2,"dm-skeleton",26)(3,"dm-skeleton",33),i())}function me(n,t){if(n&1&&(o(0,"dm-empty",8)(1,"dm-mono"),r(2,"daimon init --auto"),i()()),n&2){let e=c();y("title","No apps discovered")("hint",e.discovery().suggestion||"Run daimon init --auto in your workspace")}}function ce(n,t){if(n&1&&(o(0,"li")(1,"dm-mono"),r(2),i()()),n&2){let e=t.$implicit;d(2),m(e)}}function pe(n,t){if(n&1&&(o(0,"tr")(1,"td")(2,"dm-mono"),r(3),i()(),o(4,"td",38)(5,"dm-mono"),r(6),i()()()),n&2){let e=t.$implicit;d(3),m(e.reason),d(3),m(e.count)}}function ue(n,t){if(n&1&&(o(0,"div",34)(1,"div",28),r(2,"Rejected"),i(),o(3,"table",37)(4,"tbody"),C(5,pe,7,2,"tr",null,ae),i()()()),n&2){let e=c(2);d(5),h(e.rejectedRows())}}function ge(n,t){if(n&1&&(o(0,"li")(1,"dm-mono"),r(2),i()()),n&2){let e=t.$implicit;d(2),m(e)}}function fe(n,t){if(n&1&&(o(0,"div",34)(1,"div",28),r(2,"Warnings"),i(),o(3,"ul",39),C(4,ge,3,1,"li",null,O),i()()),n&2){let e=c(2);d(4),h(e.discovery().warnings)}}function _e(n,t){if(n&1&&(o(0,"div",36),r(1),i()),n&2){let e=c(2);d(),m(e.discovery().suggestion)}}function xe(n,t){if(n&1&&(o(0,"div",27)(1,"span",28),r(2,"Apps found"),i(),o(3,"span",29)(4,"dm-mono"),r(5),i()()(),o(6,"div",27)(7,"span",28),r(8,"Scanned"),i(),o(9,"span",29)(10,"dm-mono"),r(11),i()()(),o(12,"div",34)(13,"div",28),r(14,"Search roots"),i(),o(15,"ul",35),C(16,ce,3,1,"li",null,O),i()(),g(18,ue,7,0,"div",34),g(19,fe,6,0,"div",34),g(20,_e,2,1,"div",36)),n&2){let e=c();d(5),m(e.discovery().appsFound),d(6),m(e.discovery().scanned),d(5),h(e.discovery().searchRoots),d(2),f(e.rejectedRows().length?18:-1),d(),f(e.discovery().warnings.length?19:-1),d(),f(e.discovery().suggestion?20:-1)}}function ve(n,t){n&1&&(o(0,"div",9),r(1,"Discovery info unavailable."),i())}function ye(n,t){n&1&&v(0,"mat-spinner",14)}function Ce(n,t){n&1&&(o(0,"mat-icon"),r(1,"play_arrow"),i())}function he(n,t){n&1&&v(0,"mat-spinner",14)}function be(n,t){n&1&&(o(0,"mat-icon"),r(1,"build"),i())}function ke(n,t){if(n&1&&(o(0,"dm-mono"),r(1),i()),n&2){let e=c(2).$implicit,a=c();d(),m(a.state(e.name).detail)}}function Pe(n,t){if(n&1&&(o(0,"span"),r(1),i()),n&2){let e=c(2).$implicit,a=c();d(),m(a.state(e.name).detail)}}function Me(n,t){if(n&1&&(o(0,"div",42),g(1,ke,2,1,"dm-mono")(2,Pe,2,1,"span"),i()),n&2){let e=c().$implicit,a=c();d(),f(a.state(e.name).isPath?1:2)}}function Se(n,t){n&1&&v(0,"mat-spinner",14)}function we(n,t){n&1&&(o(0,"mat-icon"),r(1,"search"),i())}function Ee(n,t){n&1&&v(0,"mat-spinner",14)}function De(n,t){n&1&&(o(0,"mat-icon"),r(1,"build"),i())}function Oe(n,t){if(n&1){let e=T();o(0,"mat-card",6)(1,"mat-card-header")(2,"mat-card-title"),r(3),i()(),o(4,"mat-card-content")(5,"div",40)(6,"div",41),r(7),i(),o(8,"span",30),v(9,"span",31),r(10),i()(),g(11,Me,3,1,"div",42),i(),o(12,"mat-card-actions",43)(13,"button",13),b("click",function(){let l=E(e).$implicit,p=c();return D(p.runOne(l.name,!0))}),g(14,Se,1,0,"mat-spinner",14)(15,we,2,0,"mat-icon"),r(16," Dry-run "),i(),o(17,"button",44),b("click",function(){let l=E(e).$implicit,p=c();return D(p.runOne(l.name,!1))}),g(18,Ee,1,0,"mat-spinner",14)(19,De,2,0,"mat-icon"),r(20," Fix "),i()()()}if(n&2){let e=t.$implicit,a=c();d(3),m(e.title),d(4),m(e.description),d(),k("data-kind",a.state(e.name).status),d(2),P("",a.state(e.name).status," "),d(),f(a.state(e.name).detail?11:-1),d(2),y("disabled",a.busy(e.name)||a.busyAll()),d(),f(a.busy(e.name)==="dry"?14:15),d(3),y("disabled",a.busy(e.name)||a.busyAll()),d(),f(a.busy(e.name)==="fix"?18:19)}}function Ae(n,t){n&1&&v(0,"dm-skeleton",16)}function Te(n,t){n&1&&(o(0,"div",9),r(1,"No plug-ins installed. Drop a "),o(2,"dm-mono"),r(3,"doctor-*.mjs"),i(),r(4," file into "),o(5,"dm-mono"),r(6,"~/.daimon/plugins/"),i(),r(7," and restart the daemon."),i())}function Fe(n,t){if(n&1&&(o(0,"mat-card-subtitle"),r(1),i()),n&2){let e=c().$implicit;d(),m(e.description)}}function Ie(n,t){if(n&1&&(o(0,"div",45),r(1),i()),n&2){let e=c().$implicit;d(),m(e.error)}}function Re(n,t){if(n&1&&(o(0,"li")(1,"span",30),v(2,"span",31),r(3),i(),o(4,"span"),r(5),i()()),n&2){let e=t.$implicit;d(),k("data-kind",e.severity==="error"?"err":e.severity==="warn"?"warn":"ok"),d(2),m(e.severity||"info"),d(2),m(e.message)}}function Ne(n,t){if(n&1&&(o(0,"ul",35),C(1,Re,6,3,"li",null,re),i()),n&2){let e=c().$implicit;d(),h(e.findings)}}function $e(n,t){n&1&&(o(0,"div",9),r(1,"No findings."),i())}function je(n,t){if(n&1&&(o(0,"mat-card",6)(1,"mat-card-header")(2,"mat-card-title")(3,"span",30),v(4,"span",31),r(5),i(),o(6,"dm-mono"),r(7),i()(),g(8,Fe,2,1,"mat-card-subtitle"),i(),o(9,"mat-card-content"),g(10,Ie,2,1,"div",45),g(11,Ne,3,0,"ul",35)(12,$e,2,0,"div",9),o(13,"div",46)(14,"dm-mono"),r(15),i()()()()),n&2){let e=t.$implicit;d(3),k("data-kind",e.status==="ok"?"ok":"err"),d(2),P("",e.status," "),d(2),m(e.name),d(),f(e.description?8:-1),d(2),f(e.error?10:-1),d(),f(e.findings.length?11:12),d(4),m(e.file)}}function Ke(n,t){if(n&1&&(o(0,"div",5),C(1,je,16,7,"mat-card",6,ie),i()),n&2){let e=c();d(),h(e.plugins())}}function ze(n,t){n&1&&v(0,"mat-spinner",14)}function Be(n,t){n&1&&(o(0,"mat-icon"),r(1,"refresh"),i())}var Ve=[{name:"orphan-daemon",title:"Orphan daemon",description:"Daemon may be running from the wrong cwd, ignoring your local daimon.config.json"},{name:"stale-lock",title:"Stale lock",description:"Lock file exists but the daemon process is dead"},{name:"missing-search-root",title:"Missing search root",description:"Current cwd has an nx/angular/vite project but isn\u2019t configured"},{name:"corrupt-history-db",title:"Corrupt history DB",description:"History SQLite DB failed quickCheck()"}],ne=class n{api=M($);http=M(F);snack=M(L);routines=Ve;results=_(new Map);results_lastIntent=_(new Map);errored=_(new Set);loading=_(!0);discovery=_(null);daemonVersion=_("");daemonPort=_(null);configLoaded=_(!1);overview=_(null);plugins=_(null);busyMap=_(new Map);busyAll=_(!1);busyAllKind=_(null);reloading=_(!1);rejectedRows=S(()=>{let t=this.discovery();return t?Object.entries(t.rejected||{}).map(([e,a])=>({reason:e,count:a})).sort((e,a)=>a.count-e.count):[]});subtitle=S(()=>{let t=this.results(),e=0;for(let a of t.values())a.detected&&e++;return this.loading()&&t.size===0?"Checking system health\u2026":t.size===0?"Run diagnostics to see if any routines need fixing.":e===0?"All checked routines look clean.":`${e} routine${e===1?"":"s"} need${e===1?"s":""} fixing`});tokenEstimate=S(()=>120+this.api.apps().length*34);async ngOnInit(){await this.refreshAll()}async refreshAll(){this.loading.set(!0);try{let[t,e,a]=await Promise.all([this.api.getConfig().catch(()=>null),this.api.discoveryExplain().catch(()=>null),w(this.http.get("/api/overview")).catch(()=>null)]);t&&t.config&&(this.configLoaded.set(!0),this.daemonPort.set(t.config.apiPort??t.config.api?.port??null)),this.discovery.set(e),this.overview.set(a),a?.version&&this.daemonVersion.set(a.version),this.api.apps().length||await this.api.refresh();try{let l=await w(this.http.get("/api/plugins"));this.plugins.set(Array.isArray(l)?l:[])}catch{this.plugins.set([])}}finally{this.loading.set(!1)}}state(t){let e=this.results().get(t),a=this.results_lastIntent().get(t),l=this.errored().has(t);if(!e)return{status:"unknown",detail:"",isPath:!1};let p;l?p="error":a==="fix"?p=e.detected?"fixed":"clean":p=e.detected?"detected":"clean";let x=e.description||"",u=/[\\/]/.test(x)||x.includes(":\\")||x.startsWith("/");return{status:p,detail:x,isPath:u}}busy(t){return this.busyMap().get(t)}async runOne(t,e){if(!e&&!window.confirm(`Run fix for "${t}"? This will modify daemon state.`))return;let a=e?"dry":"fix";this.setBusy(t,a);try{let l=await this.api.runAutoFix({dryRun:e,permitted:[t]});this.ingestResults(l,a);let p=this.results().get(t);p?this.snack.open(e?p.detected?`${t}: issue detected`:`${t}: clean`:p.detected?`${t}: fix applied`:`${t}: no action needed`,"OK",{duration:3500}):this.snack.open(`${t}: no result returned`,"OK",{duration:3e3})}catch(l){this.markError(t,l?.message||String(l)),this.snack.open(`${t} failed: ${l?.message||l}`,"Dismiss",{duration:5e3})}finally{this.setBusy(t,null)}}async runAllDry(){this.busyAll.set(!0),this.busyAllKind.set("dry");try{let t=await this.api.runAutoFix({dryRun:!0});this.ingestResults(t,"dry"),this.snack.open("Dry-run complete","OK",{duration:2500})}catch(t){this.snack.open(`Dry-run failed: ${t?.message||t}`,"Dismiss",{duration:5e3})}finally{this.busyAll.set(!1),this.busyAllKind.set(null)}}async fixAll(){if(window.confirm("Run every fix routine without dry-run? This will modify daemon state.")){this.busyAll.set(!0),this.busyAllKind.set("fix");try{let e=await this.api.runAutoFix({dryRun:!1});this.ingestResults(e,"fix"),this.snack.open("Fix-all complete","OK",{duration:2500})}catch(e){this.snack.open(`Fix-all failed: ${e?.message||e}`,"Dismiss",{duration:5e3})}finally{this.busyAll.set(!1),this.busyAllKind.set(null)}}}async reloadConfig(){this.reloading.set(!0);try{await this.api.reloadConfig(),this.snack.open("Config reloaded","OK",{duration:2500}),await this.refreshAll()}catch(t){this.snack.open(`Reload failed: ${t?.message||t}`,"Dismiss",{duration:5e3})}finally{this.reloading.set(!1)}}setBusy(t,e){this.busyMap.update(a=>{let l=new Map(a);return e===null?l.delete(t):l.set(t,e),l})}ingestResults(t,e){let a=Array.isArray(t?.ran)?t.ran:[],l=Array.isArray(t?.skipped)?t.skipped:[],p=Array.isArray(t?.errors)?t.errors:[];if(this.results.update(x=>{let u=new Map(x);for(let s of a)u.set(s.name,s);for(let s of l)u.set(s.name,s);for(let s of p){let oe=u.get(s.name);u.set(s.name,{name:s.name,detected:oe?.detected??!1,description:s.error||"error"})}return u}),this.errored.update(x=>{let u=new Set(x);for(let s of a)u.delete(s.name);for(let s of l)u.delete(s.name);for(let s of p)u.add(s.name);return u}),this.results_lastIntent.update(x=>{let u=new Map(x);for(let s of a)u.set(s.name,e);for(let s of l)u.set(s.name,e);for(let s of p)u.set(s.name,"fix");return u}),p.length)for(let x of p)this.markError(x.name,x.error)}markError(t,e){this.results.update(a=>{let l=new Map(a);return l.set(t,{name:t,detected:!1,description:e||"error"}),l}),this.results_lastIntent.update(a=>{let l=new Map(a);return l.set(t,"fix"),l}),this.errored.update(a=>{let l=new Set(a);return l.add(t),l})}static \u0275fac=function(e){return new(e||n)};static \u0275cmp=A({type:n,selectors:[["dm-doctor-page"]],decls:80,vars:12,consts:[[1,"dm-page-header"],[1,"dm-page-sub"],["mat-icon-button","","aria-label","Refresh",3,"click","disabled"],[1,"dm-section"],[1,"dm-section-title"],[1,"dm-grid-2"],[1,"dm-card"],[1,"dm-stack"],["icon","search_off",3,"title","hint"],[1,"dm-muted"],[1,"dm-banner"],[1,"dm-banner-text"],[1,"dm-banner-actions"],["mat-stroked-button","",3,"click","disabled"],["diameter","16"],["mat-flat-button","","color","warn",3,"click","disabled"],["height","2rem","width","40%"],[1,"dm-quick"],["mat-stroked-button","","routerLink","/config"],["mat-stroked-button","","routerLink","/events"],[1,"dm-stat"],[1,"dm-stat-icon"],[1,"dm-stat-label"],[1,"dm-stat-value"],["height","1.25rem","width","60%"],["height","1rem","width","40%"],["height","1rem","width","50%"],[1,"dm-kv"],[1,"dm-k"],[1,"dm-v"],[1,"dm-pill"],[1,"dm-dot"],["height","1rem","width","70%"],["height","1rem","width","80%"],[1,"dm-block"],[1,"dm-list"],[1,"dm-callout"],[1,"dm-table"],[1,"dm-num"],[1,"dm-list","dm-warn"],[1,"dm-row-between"],[1,"dm-routine-desc"],[1,"dm-detail"],["align","end"],["mat-flat-button","","color","primary",3,"click","disabled"],[1,"dm-detail","dm-warn"],[1,"dm-detail","dm-muted"]],template:function(e,a){e&1&&(o(0,"div",0)(1,"div")(2,"h1"),r(3,"Doctor"),i(),o(4,"div",1),r(5),i()(),o(6,"button",2),b("click",function(){return a.refreshAll()}),o(7,"mat-icon"),r(8,"refresh"),i()()(),o(9,"section",3)(10,"h2",4),r(11,"System overview"),i(),o(12,"div",5)(13,"mat-card",6)(14,"mat-card-header")(15,"mat-card-title"),r(16,"Daemon"),i()(),o(17,"mat-card-content"),g(18,de,4,0,"div",7)(19,le,25,5),i()(),o(20,"mat-card",6)(21,"mat-card-header")(22,"mat-card-title"),r(23,"Discovery"),i()(),o(24,"mat-card-content"),g(25,se,4,0,"div",7)(26,me,3,2,"dm-empty",8)(27,xe,21,5)(28,ve,2,0,"div",9),i()()()(),o(29,"section",3)(30,"h2",4),r(31,"Auto-fix routines"),i(),o(32,"div",10)(33,"div",11),r(34,"Run diagnostics across every routine, or attempt all fixes in one go."),i(),o(35,"div",12)(36,"button",13),b("click",function(){return a.runAllDry()}),g(37,ye,1,0,"mat-spinner",14)(38,Ce,2,0,"mat-icon"),r(39," Run all dry-run "),i(),o(40,"button",15),b("click",function(){return a.fixAll()}),g(41,he,1,0,"mat-spinner",14)(42,be,2,0,"mat-icon"),r(43," Fix everything (be careful) "),i()()(),o(44,"div",5),C(45,Oe,21,9,"mat-card",6,ie),i()(),o(47,"section",3)(48,"h2",4),r(49,"Custom rules"),i(),g(50,Ae,1,0,"dm-skeleton",16)(51,Te,8,0,"div",9)(52,Ke,3,0,"div",5),i(),o(53,"section",3)(54,"h2",4),r(55,"Quick links"),i(),o(56,"div",17)(57,"button",18)(58,"mat-icon"),r(59,"tune"),i(),r(60," Open Config editor "),i(),o(61,"button",19)(62,"mat-icon"),r(63,"timeline"),i(),r(64," View Events "),i(),o(65,"button",13),b("click",function(){return a.reloadConfig()}),g(66,ze,1,0,"mat-spinner",14)(67,Be,2,0,"mat-icon"),r(68," Reload config "),i(),o(69,"div",20)(70,"div",21)(71,"mat-icon"),r(72,"token"),i()(),o(73,"div")(74,"div",22),r(75,"API token footprint"),i(),o(76,"div",23)(77,"dm-mono"),r(78),i(),r(79," per Claude session"),i()()()()()),e&2&&(d(5),m(a.subtitle()),d(),y("disabled",a.loading()),d(12),f(a.loading()&&!a.configLoaded()?18:19),d(7),f(a.loading()&&!a.discovery()?25:a.discovery()&&a.discovery().appsFound===0?26:a.discovery()?27:28),d(11),y("disabled",a.busyAll()),d(),f(a.busyAll()&&a.busyAllKind()==="dry"?37:38),d(3),y("disabled",a.busyAll()),d(),f(a.busyAll()&&a.busyAllKind()==="fix"?41:42),d(4),h(a.routines),d(5),f(a.plugins()===null?50:a.plugins().length===0?51:52),d(15),y("disabled",a.reloading()),d(),f(a.reloading()?66:67),d(12),P("~ ",a.tokenEstimate()," tokens"))},dependencies:[I,ee,U,Y,J,Z,X,G,V,B,z,N,R,K,j,q,te,H,Q,W],styles:["[_nghost-%COMP%]{display:block;max-width:1200px;margin:0 auto}.dm-section[_ngcontent-%COMP%]{margin-bottom:1.25rem}.dm-section-title[_ngcontent-%COMP%]{margin:0 0 .5rem;font:500 .6875rem/1rem Roboto;color:var(--mat-sys-on-surface-variant);letter-spacing:.06em;text-transform:uppercase}.dm-grid-2[_ngcontent-%COMP%]{display:grid;gap:.75rem;grid-template-columns:repeat(2,minmax(0,1fr))}@media(max-width:800px){.dm-grid-2[_ngcontent-%COMP%]{grid-template-columns:1fr}}.dm-card[_ngcontent-%COMP%]{background:var(--mat-sys-surface-container-low)}.dm-stack[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:.5rem}.dm-kv[_ngcontent-%COMP%]{display:flex;align-items:baseline;justify-content:space-between;padding:.35rem 0;border-bottom:1px solid var(--mat-sys-outline-variant)}.dm-kv[_ngcontent-%COMP%]:last-child{border-bottom:0}.dm-k[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-size:.8125rem}.dm-v[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface)}.dm-block[_ngcontent-%COMP%]{margin-top:.75rem}.dm-block[_ngcontent-%COMP%] .dm-k[_ngcontent-%COMP%]{display:block;margin-bottom:.35rem}.dm-list[_ngcontent-%COMP%]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.25rem}.dm-list[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{padding:.25rem .5rem;background:var(--mat-sys-surface-container);border-radius:6px;overflow-wrap:anywhere}.dm-warn[_ngcontent-%COMP%] li[_ngcontent-%COMP%]{color:var(--mat-sys-error)}.dm-table[_ngcontent-%COMP%]{width:100%;border-collapse:collapse;font-size:.8125rem}.dm-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{padding:.25rem .5rem;border-bottom:1px solid var(--mat-sys-outline-variant)}.dm-table[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%]{border-bottom:0}.dm-num[_ngcontent-%COMP%]{text-align:right;color:var(--mat-sys-on-surface-variant)}.dm-callout[_ngcontent-%COMP%]{margin-top:.75rem;padding:.65rem .85rem;border-radius:10px;background:color-mix(in oklch,var(--mat-sys-tertiary) 12%,transparent);border:1px solid color-mix(in oklch,var(--mat-sys-tertiary) 28%,transparent);color:var(--mat-sys-on-surface);font-size:.875rem}.dm-muted[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-size:.875rem}.dm-pill[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:.4rem;padding:2px 10px;border-radius:999px;border:1px solid var(--mat-sys-outline-variant);background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface);font:500 .75rem/1rem Roboto;letter-spacing:.025rem}.dm-pill[_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{width:8px;height:8px;border-radius:999px;background:var(--mat-sys-outline)}.dm-pill[data-kind=ok][_ngcontent-%COMP%], .dm-pill[data-kind=clean][_ngcontent-%COMP%], .dm-pill[data-kind=fixed][_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-primary) 12%,transparent);border-color:color-mix(in oklch,var(--mat-sys-primary) 28%,transparent)}.dm-pill[data-kind=ok][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%], .dm-pill[data-kind=clean][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%], .dm-pill[data-kind=fixed][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{background:var(--mat-sys-primary)}.dm-pill[data-kind=detected][_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-tertiary) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-tertiary) 28%,transparent)}.dm-pill[data-kind=detected][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{background:var(--mat-sys-tertiary)}.dm-pill[data-kind=err][_ngcontent-%COMP%], .dm-pill[data-kind=error][_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-error) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-error) 30%,transparent);color:var(--mat-sys-error)}.dm-pill[data-kind=err][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%], .dm-pill[data-kind=error][_ngcontent-%COMP%] .dm-dot[_ngcontent-%COMP%]{background:var(--mat-sys-error)}.dm-banner[_ngcontent-%COMP%]{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.5rem .85rem;margin-bottom:.75rem;background:var(--mat-sys-surface-container);border:1px solid var(--mat-sys-outline-variant);border-radius:10px}.dm-banner-text[_ngcontent-%COMP%]{font-size:.875rem;color:var(--mat-sys-on-surface-variant)}.dm-banner-actions[_ngcontent-%COMP%]{display:flex;gap:.5rem}@media(max-width:700px){.dm-banner[_ngcontent-%COMP%]{flex-direction:column;align-items:stretch}.dm-banner-actions[_ngcontent-%COMP%]{flex-wrap:wrap}}.dm-row-between[_ngcontent-%COMP%]{display:flex;align-items:flex-start;justify-content:space-between;gap:.75rem}.dm-routine-desc[_ngcontent-%COMP%]{font-size:.875rem;color:var(--mat-sys-on-surface-variant);flex:1}.dm-detail[_ngcontent-%COMP%]{margin-top:.75rem;padding:.5rem .65rem;background:var(--mat-sys-surface-container);border-radius:8px;font-size:.8125rem;overflow-wrap:anywhere}.dm-quick[_ngcontent-%COMP%]{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:.75rem}.dm-quick[_ngcontent-%COMP%] button[_ngcontent-%COMP%]{justify-content:flex-start;padding:.5rem .75rem;height:auto;min-height:40px}.dm-stat[_ngcontent-%COMP%]{display:flex;align-items:center;gap:.625rem;padding:.5rem .75rem;border:1px solid var(--mat-sys-outline-variant);border-radius:10px;background:var(--mat-sys-surface-container-low)}.dm-stat-icon[_ngcontent-%COMP%]{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:color-mix(in oklch,var(--mat-sys-primary) 14%,transparent);color:var(--mat-sys-primary)}.dm-stat-icon[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:16px;width:16px;height:16px}.dm-stat-label[_ngcontent-%COMP%]{font-size:.75rem;color:var(--mat-sys-on-surface-variant);text-transform:uppercase;letter-spacing:.025rem}.dm-stat-value[_ngcontent-%COMP%]{font-size:.875rem;color:var(--mat-sys-on-surface)}mat-spinner[_ngcontent-%COMP%]{display:inline-block;margin-right:.35rem}"],changeDetection:0})};export{ne as DoctorPageComponent};
@@ -1 +0,0 @@
1
- import{d as de}from"./chunk-UUJWPV5O.js";import{a as ee,b as te,c as ne,d as ie,e as oe,g as ae,h as re,k as se,l as le}from"./chunk-K2SFF47Z.js";import"./chunk-YHBNUNU3.js";import"./chunk-KRC72WWY.js";import{b as Y,f as Q,h as q,m as G}from"./chunk-6Z4FDREI.js";import"./chunk-3ZFFKHPU.js";import{b as H,c as J,d as U}from"./chunk-LBWOIG7N.js";import"./chunk-AGN2F6JP.js";import"./chunk-SR4HVFOB.js";import{c as X,d as Z}from"./chunk-WOMCRDMJ.js";import{a as z,b as K}from"./chunk-VHALTUPL.js";import"./chunk-YNQPX5G6.js";import"./chunk-6MTVWBQQ.js";import"./chunk-TGSV7ZHM.js";import"./chunk-VMW35ZNT.js";import"./chunk-FRKUCFVI.js";import"./chunk-B2DPS6BL.js";import{c as B}from"./chunk-PRLUGTKR.js";import{e as j,f as A}from"./chunk-UC7AWK4C.js";import{d as W}from"./chunk-X4RGWMLE.js";import"./chunk-JWXROQJJ.js";import{h as V}from"./chunk-EBGPIJ7S.js";import{Db as b,Eb as c,Fb as p,Hb as L,Ib as E,Jb as k,Kb as _,Lb as a,Mb as r,Nb as F,Sb as T,Ub as h,Wb as m,_a as o,ea as D,gc as w,ic as s,ja as x,jc as u,ka as M,kc as y,pb as N,ta as g,tc as R,yc as P}from"./chunk-O76B43BY.js";var ce=t=>["/apps",t],pe=(t,n)=>n.name,ue=(t,n)=>n.key;function ve(t,n){t&1&&(a(0,"span",18),s(1,"\xB7"),r(),a(2,"span",19),s(3,"paused"),r())}function ge(t,n){if(t&1&&(a(0,"span",18),s(1,"\xB7"),r(),a(2,"span"),s(3),r()),t&2){let e=m();o(3),y("",e.pendingCount()," new while paused")}}function _e(t,n){if(t&1&&(a(0,"mat-option",10),s(1),r()),t&2){let e=n.$implicit;_("value",e.name),o(),u(e.name)}}function fe(t,n){if(t&1){let e=T();a(0,"button",20),h("click",function(){x(e);let d=m();return M(d.textFilter.set(""))}),a(1,"mat-icon"),s(2,"close"),r()()}}function he(t,n){if(t&1){let e=T();a(0,"button",21),h("click",function(){let d=x(e).$implicit,v=m();return M(v.toggleType(d))}),s(1),r()}if(t&2){let e=n.$implicit,i=m();w("dm-chip-active",i.typeFilter().has(e)),b("data-kind",e),o(),y(" ",e," ")}}function ye(t,n){if(t&1){let e=T();a(0,"button",22),h("click",function(){x(e);let d=m();return M(d.clearTypes())}),a(1,"mat-icon"),s(2,"close"),r()()}}function Ce(t,n){t&1&&F(0,"dm-empty",23)}function xe(t,n){t&1&&F(0,"dm-empty",24)}function Me(t,n){if(t&1&&c(0,Ce,1,0,"dm-empty",23)(1,xe,1,0,"dm-empty",24),t&2){let e=m();p(e.liveEvents().length===0?0:1)}}function be(t,n){if(t&1&&(a(0,"li",25)(1,"span",32),s(2),r()()),t&2){let e=m().$implicit;o(2),u(e.gapLabel)}}function Ee(t,n){if(t&1&&(a(0,"a",29)(1,"dm-mono"),s(2),r()()),t&2){let e=m().$implicit;_("routerLink",R(2,ce,e.ev.app)),o(2),u(e.ev.app)}}function ke(t,n){t&1&&(a(0,"span",30),s(1,"\u2014"),r())}function Fe(t,n){if(t&1&&(a(0,"dm-mono"),s(1),r(),a(2,"span",33),s(3,"\u2192"),r(),a(4,"dm-mono"),s(5),r()),t&2){let e=m().$implicit;o(),u(e.ev.from??"?"),o(4),u(e.ev.to??"?")}}function Te(t,n){if(t&1&&s(0),t&2){let e=m().$implicit;y(" ",e.ev.message??""," ")}}function we(t,n){if(t&1&&(c(0,be,3,1,"li",25),a(1,"li",26)(2,"span",27)(3,"dm-mono"),s(4),r()(),a(5,"span",28),s(6),r(),c(7,Ee,3,4,"a",29)(8,ke,2,0,"span",30),a(9,"span",31),c(10,Fe,6,2)(11,Te,1,1),r()()),t&2){let e=n.$implicit,i=m(2);p(e.divider?0:-1),o(),w("dm-flash",e.flash),b("data-kind",e.ev.type),o(),_("matTooltip",i.absTime(e.ev.ts)),o(2),u(i.rel(e.ev.ts)),o(),b("data-kind",e.ev.type),o(),u(e.ev.type),o(),p(e.ev.app?7:8),o(3),p(e.ev.type==="status"&&(e.ev.from||e.ev.to)?10:11)}}function Pe(t,n){if(t&1&&(a(0,"ol",17),E(1,we,12,10,null,null,ue),r()),t&2){let e=m();o(),k(e.rendered())}}var Oe=["status","health","error","compile","log"];function Se(t,n){let e=Math.max(0,Math.floor((n-t)/1e3));if(e<1)return"just now";if(e<60)return`${e}s ago`;let i=Math.floor(e/60),d=e%60;return i<60?d?`${i}m ${d}s ago`:`${i}m ago`:`${Math.floor(i/60)}h ${i%60}m ago`}var me=class t{api=D(W);types=Oe;paused=g(!1);appFilter=g("");textFilter=g("");typeFilter=g(new Set);now=g(Date.now());snapshot=g(null);lastSeenTs=g(0);tickTimer;liveEvents=P(()=>this.snapshot()??this.api.events());pendingCount=P(()=>{let n=this.snapshot();if(!n)return 0;let e=this.api.events();return Math.max(0,e.length-n.length)});rendered=P(()=>{let n=this.liveEvents(),e=this.appFilter(),i=this.textFilter().toLowerCase(),d=this.typeFilter(),v=this.lastSeenTs(),C=[];for(let l of n)e&&l.app!==e||d.size&&!d.has(l.type)||i&&!`${l.app??""} ${l.type} ${l.message??""} ${l.from??""} ${l.to??""}`.toLowerCase().includes(i)||C.push(l);let S=[];for(let l=0;l<C.length;l++){let f=C[l],O=C[l+1],I=O?f.ts-O.ts:0,$=!!O&&I>3e4;S.push({key:`${f.ts}:${l}`,ev:f,divider:$,gapLabel:$?Ie(I):"",flash:f.ts>v})}return S.sort((l,f)=>f.ev.ts-l.ev.ts)});ngOnInit(){this.lastSeenTs.set(Date.now()),this.tickTimer=setInterval(()=>{this.now.set(Date.now());let n=this.api.events();n.length&&this.lastSeenTs.set(n[n.length-1].ts)},1e3)}ngOnDestroy(){this.tickTimer&&clearInterval(this.tickTimer)}togglePause(){this.paused()?(this.paused.set(!1),this.snapshot.set(null)):(this.snapshot.set(this.api.events().slice()),this.paused.set(!0))}toggleType(n){this.typeFilter.update(e=>{let i=new Set(e);return i.has(n)?i.delete(n):i.add(n),i})}clearTypes(){this.typeFilter.set(new Set)}rel(n){return Se(n,this.now())}absTime(n){return new Date(n).toLocaleString()}static \u0275fac=function(e){return new(e||t)};static \u0275cmp=N({type:t,selectors:[["dm-events-feed"]],decls:37,vars:15,consts:[[1,"dm-page-header"],[1,"dm-count"],[1,"dm-page-sub"],[1,"dm-conn"],[1,"dm-conn-dot"],[1,"dm-header-actions"],["mat-stroked-button","",3,"click","matTooltip"],[1,"dm-toolbar"],["appearance","outline",1,"dm-app-filter"],[3,"ngModelChange","ngModel"],[3,"value"],["appearance","outline",1,"dm-text-filter"],["matInput","","placeholder","filter message / app",3,"ngModelChange","ngModel"],["matSuffix","","mat-icon-button",""],[1,"dm-type-chips"],[1,"dm-chip",3,"dm-chip-active"],[1,"dm-chip","dm-chip-clear"],[1,"dm-list"],[1,"dm-sep"],[1,"dm-paused-tag"],["matSuffix","","mat-icon-button","",3,"click"],[1,"dm-chip",3,"click"],[1,"dm-chip","dm-chip-clear",3,"click"],["icon","timeline","title","Quiet","hint","No events in this session \u2014 start an app to see status transitions, errors, and compiles"],["icon","filter_alt_off","title","No matches","hint","Adjust filters to see events"],[1,"dm-divider"],[1,"dm-event"],[1,"dm-time",3,"matTooltip"],[1,"dm-type"],[1,"dm-app",3,"routerLink"],[1,"dm-app","dm-app-empty"],[1,"dm-msg"],[1,"dm-divider-label"],[1,"dm-arrow"]],template:function(e,i){e&1&&(a(0,"div",0)(1,"div")(2,"h1"),s(3,"Events "),a(4,"span",1),s(5),r()(),a(6,"div",2)(7,"span",3),F(8,"span",4),s(9),r(),c(10,ve,4,0),c(11,ge,4,1),r()(),a(12,"div",5)(13,"button",6),h("click",function(){return i.togglePause()}),a(14,"mat-icon"),s(15),r(),s(16),r()()(),a(17,"div",7)(18,"mat-form-field",8)(19,"mat-label"),s(20,"App"),r(),a(21,"mat-select",9),h("ngModelChange",function(v){return i.appFilter.set(v)}),a(22,"mat-option",10),s(23,"All apps"),r(),E(24,_e,2,2,"mat-option",10,pe),r()(),a(26,"mat-form-field",11)(27,"mat-label"),s(28,"Search"),r(),a(29,"input",12),h("ngModelChange",function(v){return i.textFilter.set(v)}),r(),c(30,fe,3,0,"button",13),r(),a(31,"div",14),E(32,he,2,4,"button",15,L),c(34,ye,3,0,"button",16),r()(),c(35,Me,2,1)(36,Pe,3,0,"ol",17)),e&2&&(o(5),y("\xB7 ",i.liveEvents().length),o(2),w("dm-conn-on",i.api.connected()),o(2),y(" ",i.api.connected()?"live":"disconnected"," "),o(),p(i.paused()?10:-1),o(),p(i.paused()&&i.pendingCount()>0?11:-1),o(2),_("matTooltip",i.paused()?"Resume feed":"Pause feed"),o(2),u(i.paused()?"play_arrow":"pause"),o(),y(" ",i.paused()?"Resume":"Pause"," "),o(5),_("ngModel",i.appFilter()),o(),_("value",""),o(2),k(i.api.apps()),o(5),_("ngModel",i.textFilter()),o(),p(i.textFilter()?30:-1),o(2),k(i.types),o(2),p(i.typeFilter().size>0?34:-1),o(),p(i.rendered().length===0?35:36))},dependencies:[V,G,Y,Q,q,B,ie,ne,ee,te,re,ae,oe,le,se,de,U,J,H,A,j,K,z,X,Z],styles:["[_nghost-%COMP%]{display:block}.dm-count[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);font-weight:400}.dm-conn[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:.35rem}.dm-conn-dot[_ngcontent-%COMP%]{width:7px;height:7px;border-radius:999px;background:var(--mat-sys-outline)}.dm-conn-on[_ngcontent-%COMP%] .dm-conn-dot[_ngcontent-%COMP%]{background:var(--mat-sys-primary);box-shadow:0 0 0 3px color-mix(in oklch,var(--mat-sys-primary) 24%,transparent)}.dm-sep[_ngcontent-%COMP%]{color:var(--mat-sys-outline);margin:0 .15rem}.dm-paused-tag[_ngcontent-%COMP%]{color:var(--mat-sys-tertiary);font-weight:500}.dm-toolbar[_ngcontent-%COMP%]{display:flex;flex-wrap:wrap;gap:.75rem;align-items:center;margin-bottom:.5rem}.dm-app-filter[_ngcontent-%COMP%]{width:12rem}.dm-text-filter[_ngcontent-%COMP%]{flex:1;min-width:14rem;max-width:28rem}.dm-type-chips[_ngcontent-%COMP%]{display:flex;gap:.35rem;flex-wrap:wrap}.dm-chip[_ngcontent-%COMP%]{border:1px solid var(--mat-sys-outline-variant);background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface-variant);border-radius:999px;padding:4px 12px;font:500 .75rem/1rem Roboto;cursor:pointer;letter-spacing:.025rem}.dm-chip[_ngcontent-%COMP%]:hover{background:var(--mat-sys-surface-container-high)}.dm-chip-active[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface)}.dm-chip-clear[_ngcontent-%COMP%]{display:inline-flex;align-items:center;padding:2px 8px}.dm-chip-clear[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:16px;width:16px;height:16px}.dm-list[_ngcontent-%COMP%]{list-style:none;margin:0;padding:0;border:1px solid var(--mat-sys-outline-variant);border-radius:10px;background:var(--mat-sys-surface-container-lowest);overflow:hidden}.dm-event[_ngcontent-%COMP%]{display:grid;grid-template-columns:7.5rem max-content 10rem 1fr;gap:.75rem;align-items:center;height:28px;padding:0 .75rem;border-top:1px solid var(--mat-sys-outline-variant);font-size:.8125rem;color:var(--mat-sys-on-surface)}.dm-event[_ngcontent-%COMP%]:first-child{border-top:0}.dm-time[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant)}.dm-type[_ngcontent-%COMP%]{display:inline-flex;align-items:center;justify-content:center;padding:1px 8px;border-radius:999px;font:500 .6875rem/1rem Roboto;letter-spacing:.03rem;border:1px solid var(--mat-sys-outline-variant);text-transform:lowercase;white-space:nowrap}.dm-type[data-kind=status][_ngcontent-%COMP%], .dm-chip[data-kind=status].dm-chip-active[_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-primary) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-primary) 30%,transparent);color:var(--mat-sys-primary)}.dm-type[data-kind=health][_ngcontent-%COMP%], .dm-chip[data-kind=health].dm-chip-active[_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-secondary) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-secondary) 30%,transparent);color:var(--mat-sys-secondary)}.dm-type[data-kind=error][_ngcontent-%COMP%], .dm-chip[data-kind=error].dm-chip-active[_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-error) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-error) 32%,transparent);color:var(--mat-sys-error)}.dm-type[data-kind=compile][_ngcontent-%COMP%], .dm-chip[data-kind=compile].dm-chip-active[_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-tertiary) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-tertiary) 30%,transparent);color:var(--mat-sys-tertiary)}.dm-type[data-kind=log][_ngcontent-%COMP%], .dm-chip[data-kind=log].dm-chip-active[_ngcontent-%COMP%]{background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface-variant)}.dm-app[_ngcontent-%COMP%]{text-decoration:none;color:var(--mat-sys-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dm-app[_ngcontent-%COMP%]:hover{text-decoration:underline}.dm-app-empty[_ngcontent-%COMP%]{color:var(--mat-sys-outline)}.dm-msg[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:.35rem}.dm-arrow[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant)}.dm-divider[_ngcontent-%COMP%]{height:18px;display:flex;align-items:center;justify-content:center;border-top:1px solid var(--mat-sys-outline-variant);background:var(--mat-sys-surface-container)}.dm-divider-label[_ngcontent-%COMP%]{font:400 .6875rem/1rem Roboto;color:var(--mat-sys-on-surface-variant);letter-spacing:.04rem}.dm-flash[_ngcontent-%COMP%]{animation:_ngcontent-%COMP%_dm-event-pulse .6s var(--dm-motion-easing)}@keyframes _ngcontent-%COMP%_dm-event-pulse{0%{background:color-mix(in oklch,var(--mat-sys-primary) 24%,transparent)}to{background:transparent}}@media(prefers-reduced-motion:reduce){.dm-flash[_ngcontent-%COMP%]{animation:none}}"],changeDetection:0})};function Ie(t){let n=Math.floor(t/1e3);if(n<60)return`${n}s gap`;let e=Math.floor(n/60);return e<60?`${e}m gap`:`${Math.floor(e/60)}h ${e%60}m gap`}export{me as EventsFeedComponent};
@@ -1 +0,0 @@
1
- import{a as te,b as ne,c as ie,d as ae,e as oe,g as re,h as se,k as le,l as me}from"./chunk-K2SFF47Z.js";import"./chunk-YHBNUNU3.js";import"./chunk-KRC72WWY.js";import{b as Q,f as K,h as j,m as z}from"./chunk-6Z4FDREI.js";import"./chunk-3ZFFKHPU.js";import{b as G,c as J,d as W}from"./chunk-LBWOIG7N.js";import"./chunk-AGN2F6JP.js";import"./chunk-SR4HVFOB.js";import{a as X,b as Y,c as Z,d as ee}from"./chunk-WOMCRDMJ.js";import{a as $,b as U}from"./chunk-VHALTUPL.js";import"./chunk-YNQPX5G6.js";import"./chunk-6MTVWBQQ.js";import"./chunk-TGSV7ZHM.js";import"./chunk-VMW35ZNT.js";import"./chunk-FRKUCFVI.js";import"./chunk-B2DPS6BL.js";import{c as L}from"./chunk-PRLUGTKR.js";import{e as A,f as V}from"./chunk-UC7AWK4C.js";import{a as B,d as H}from"./chunk-X4RGWMLE.js";import"./chunk-JWXROQJJ.js";import{h as N}from"./chunk-EBGPIJ7S.js";import{Db as x,Eb as g,Fb as f,Gb as I,Hb as O,Ib as v,Jb as y,Kb as u,Lb as o,Mb as a,Nb as b,Sb as M,Ub as h,Wb as d,_a as s,ea as w,gc as T,ic as r,ja as _,jc as p,ka as C,kc as k,pb as q,s as E,ta as c,tc as D,yc as P,za as R,zc as F}from"./chunk-O76B43BY.js";var ue=n=>["/apps",n],he=(n,t)=>t.value;function ge(n,t){if(n&1&&b(0,"dm-status-pill",4),n&2){let e=t;u("status",e.status)("health",e.health)}}function fe(n,t){if(n&1&&(o(0,"span"),r(1,"Last refreshed "),o(2,"dm-mono"),r(3),a()()),n&2){let e=d();s(3),p(e.lastRefreshedLabel())}}function _e(n,t){n&1&&(o(0,"span"),r(1,"Loading\u2026"),a())}function Ce(n,t){n&1&&(o(0,"span",2),r(1,"\xB7"),a(),o(2,"span",10),r(3,"paused"),a())}function xe(n,t){n&1&&(o(0,"dm-empty",9)(1,"a",11),r(2,"Go to apps"),a()())}function ve(n,t){if(n&1&&(o(0,"mat-option",15),r(1),a()),n&2){let e=t.$implicit;u("value",e.value),s(),p(e.label)}}function ye(n,t){if(n&1){let e=M();o(0,"button",26),h("click",function(){let l=_(e).$implicit,m=d(2);return C(m.toggleMethod(l))}),r(1),a()}if(n&2){let e=t.$implicit,i=d(2);T("dm-chip-active",i.methodFilter().has(e)),x("data-method",e),s(),k(" ",e," ")}}function be(n,t){if(n&1){let e=M();o(0,"button",26),h("click",function(){let l=_(e).$implicit,m=d(2);return C(m.toggleStatus(l))}),r(1),a()}if(n&2){let e=t.$implicit,i=d(2);T("dm-chip-active",i.statusFilter().has(e)),x("data-bucket",e),s(),k(" ",e," ")}}function Me(n,t){if(n&1){let e=M();o(0,"button",27),h("click",function(){_(e);let l=d(2);return C(l.pathQuery.set(""))}),o(1,"mat-icon"),r(2,"close"),a()()}}function Pe(n,t){n&1&&(o(0,"div",22),b(1,"dm-skeleton",28)(2,"dm-skeleton",28)(3,"dm-skeleton",28)(4,"dm-skeleton",28),a())}function Se(n,t){n&1&&b(0,"dm-empty",23)}function ke(n,t){n&1&&b(0,"dm-empty",24)}function we(n,t){if(n&1&&(o(0,"tr")(1,"td",30)(2,"dm-mono")(3,"span",35),r(4),a()()(),o(5,"td",31)(6,"dm-mono")(7,"span",36),r(8),a()()(),o(9,"td",32)(10,"dm-mono")(11,"span",37),r(12),a()()(),o(13,"td",33)(14,"dm-mono")(15,"span",38),r(16),a()()(),o(17,"td",34)(18,"dm-mono"),r(19),a()()()),n&2){let e=t.$implicit,i=d(3);s(3),u("matTooltip",i.absTs(e.ts)),s(),p(i.relTs(e.ts)),s(3),x("data-method",e.method),s(),p(e.method),s(3),x("data-bucket",i.bucketOf(e.status)),s(),p(e.status),s(3),u("title",e.path),s(),p(e.path),s(3),p(e.durationMs)}}function Oe(n,t){if(n&1&&(o(0,"div",25)(1,"table",29)(2,"thead")(3,"tr")(4,"th",30),r(5,"Time"),a(),o(6,"th",31),r(7,"Method"),a(),o(8,"th",32),r(9,"Status"),a(),o(10,"th",33),r(11,"Path"),a(),o(12,"th",34),r(13,"ms"),a()()(),o(14,"tbody"),v(15,we,20,9,"tr",null,I),a()()()),n&2){let e=d(2);s(15),y(e.filtered())}}function Te(n,t){if(n&1){let e=M();o(0,"div",12)(1,"mat-form-field",13)(2,"mat-label"),r(3,"Since"),a(),o(4,"mat-select",14),h("ngModelChange",function(l){_(e);let m=d();return C(m.since.set(l))}),v(5,ve,2,2,"mat-option",15,he),a()(),o(7,"div",16)(8,"span",17),r(9,"Methods"),a(),v(10,ye,2,4,"button",18,O),a(),o(12,"div",16)(13,"span",17),r(14,"Status"),a(),v(15,be,2,4,"button",18,O),a(),o(17,"mat-form-field",19)(18,"mat-label"),r(19,"Path contains"),a(),o(20,"input",20),h("ngModelChange",function(l){_(e);let m=d();return C(m.pathQuery.set(l))}),a(),g(21,Me,3,0,"button",21),a()(),g(22,Pe,5,0,"div",22)(23,Se,1,0,"dm-empty",23)(24,ke,1,0,"dm-empty",24)(25,Oe,17,0,"div",25)}if(n&2){let e=d();s(4),u("ngModel",e.since()),s(),y(e.sinceOptions),s(5),y(e.methods),s(5),y(e.statusBuckets),s(5),u("ngModel",e.pathQuery()),s(),f(e.pathQuery()?21:-1),s(),f(e.loading()&&e.rows().length===0?22:e.filtered().length===0&&e.rows().length===0?23:e.filtered().length===0?24:25)}}var Ee=["GET","POST","PUT","DELETE","PATCH"],Re=["2xx","3xx","4xx","5xx"],qe=[{value:"5m",label:"5m"},{value:"15m",label:"15m"},{value:"1h",label:"1h"},{value:"all",label:"All"}],Ie=5e3;function de(n,t){let e=Math.max(0,Math.floor((t-n)/1e3));if(e<1)return"just now";if(e<60)return`${e}s ago`;let i=Math.floor(e/60);if(i<60)return`${i}m ago`;let l=Math.floor(i/60);return l<24?`${l}h ago`:`${Math.floor(l/24)}d ago`}function ce(n){return n>=200&&n<300?"2xx":n>=300&&n<400?"3xx":n>=400&&n<500?"4xx":n>=500&&n<600?"5xx":null}var pe=class n{name="";api=w(H);http=w(B);methods=Ee;statusBuckets=Re;sinceOptions=qe;loading=c(!0);rows=c([]);since=c("5m");methodFilter=c(new Set);statusFilter=c(new Set);pathQuery=c("");paused=c(!1);lastRefreshed=c(null);tick=c(0);currentApp=P(()=>this.name?this.api.byName(this.name):void 0);unknownApp=P(()=>this.name?this.api.ready()?!this.api.byName(this.name):!1:!0);filtered=P(()=>{let t=this.rows(),e=this.methodFilter(),i=this.statusFilter(),l=this.pathQuery().trim().toLowerCase();return t.filter(m=>{if(e.size>0&&!e.has(m.method.toUpperCase()))return!1;if(i.size>0){let S=ce(m.status);if(!S||!i.has(S))return!1}return!(l&&!m.path.toLowerCase().includes(l))}).sort((m,S)=>S.ts-m.ts)});lastRefreshedLabel=P(()=>{this.tick();let t=this.lastRefreshed();return t?de(t,Date.now()):"\u2014"});refreshTimer;tickTimer;sinceFirst=!0;constructor(){F(()=>{let t=this.since();if(this.sinceFirst){this.sinceFirst=!1;return}this.refresh()})}ngOnInit(){this.refresh(),this.refreshTimer=setInterval(()=>{this.paused()||this.refresh(!0)},Ie),this.tickTimer=setInterval(()=>this.tick.update(t=>t+1),1e3)}ngOnChanges(t){"name"in t&&!t.name.firstChange&&(this.rows.set([]),this.refresh())}ngOnDestroy(){this.refreshTimer&&clearInterval(this.refreshTimer),this.tickTimer&&clearInterval(this.tickTimer)}togglePause(){this.paused.update(t=>!t)}toggleMethod(t){this.methodFilter.update(e=>{let i=new Set(e);return i.has(t)?i.delete(t):i.add(t),i})}toggleStatus(t){this.statusFilter.update(e=>{let i=new Set(e);return i.has(t)?i.delete(t):i.add(t),i})}async refresh(t=!1){if(this.name){t||this.loading.set(!0);try{let e=this.since(),i=e==="all"?"":`?since=${encodeURIComponent(e)}`,l=`/api/apps/${encodeURIComponent(this.name)}/requests${i}`,m=await E(this.http.get(l));this.rows.set(Array.isArray(m)?m:[]),this.lastRefreshed.set(Date.now())}catch{}finally{t||this.loading.set(!1)}}}relTs(t){return this.tick(),de(t,Date.now())}absTs(t){return new Date(t).toLocaleString()}bucketOf(t){return ce(t)}static \u0275fac=function(e){return new(e||n)};static \u0275cmp=q({type:n,selectors:[["dm-requests-page"]],inputs:{name:"name"},features:[R],decls:29,vars:11,consts:[[1,"dm-page-header"],["matTooltip","Back to app",1,"dm-back",3,"routerLink"],[1,"dm-sep"],[1,"dm-app"],[3,"status","health"],[1,"dm-page-sub"],[1,"dm-header-actions"],["mat-stroked-button","",3,"click","matTooltip"],["mat-stroked-button","","matTooltip","Refresh now",3,"click"],["icon","search_off","title","Unknown app","hint","No app with that name. Head back to the apps list."],[1,"dm-paused"],["routerLink","/",1,"dm-empty-link"],[1,"dm-toolbar"],["appearance","outline",1,"dm-since"],[3,"ngModelChange","ngModel"],[3,"value"],[1,"dm-chip-group"],[1,"dm-chip-label"],[1,"dm-chip",3,"dm-chip-active"],["appearance","outline",1,"dm-path-filter"],["matInput","","placeholder","/api/...",3,"ngModelChange","ngModel"],["matSuffix","","mat-icon-button",""],[1,"dm-skel-rows"],["icon","hourglass_empty","title","No requests yet","hint","Either no traffic has hit the dev server, or requestLog.enabled is false in your config."],["icon","filter_alt_off","title","No matching requests","hint","Adjust filters to see more rows."],[1,"dm-table-wrap"],[1,"dm-chip",3,"click"],["matSuffix","","mat-icon-button","",3,"click"],["height","2rem"],[1,"dm-req-table"],[1,"dm-col-time"],[1,"dm-col-method"],[1,"dm-col-status"],[1,"dm-col-path"],[1,"dm-col-dur"],[3,"matTooltip"],[1,"dm-method"],[1,"dm-status"],[1,"dm-path",3,"title"]],template:function(e,i){if(e&1&&(o(0,"div",0)(1,"div")(2,"h1")(3,"a",1)(4,"mat-icon"),r(5,"arrow_back"),a()(),o(6,"span"),r(7,"Requests"),a(),o(8,"span",2),r(9,"\xB7"),a(),o(10,"dm-mono")(11,"span",3),r(12),a()(),g(13,ge,1,2,"dm-status-pill",4),a(),o(14,"div",5),g(15,fe,4,1,"span")(16,_e,2,0,"span"),g(17,Ce,4,0),a()(),o(18,"div",6)(19,"button",7),h("click",function(){return i.togglePause()}),o(20,"mat-icon"),r(21),a(),r(22),a(),o(23,"button",8),h("click",function(){return i.refresh()}),o(24,"mat-icon"),r(25,"refresh"),a(),r(26," Refresh "),a()()(),g(27,xe,3,0,"dm-empty",9)(28,Te,26,4)),e&2){let l;s(3),u("routerLink",D(9,ue,i.name)),s(9),p(i.name),s(),f((l=i.currentApp())?13:-1,l),s(2),f(i.lastRefreshed()?15:16),s(2),f(i.paused()?17:-1),s(2),u("matTooltip",i.paused()?"Resume auto-refresh":"Pause auto-refresh"),s(2),p(i.paused()?"play_arrow":"pause"),s(),k(" ",i.paused()?"Resume":"Pause"," "),s(5),f(i.unknownApp()?27:28)}},dependencies:[N,z,Q,K,j,L,ae,ie,te,ne,se,re,oe,me,le,W,J,G,V,A,U,$,X,Z,Y,ee],styles:['[_nghost-%COMP%]{display:block}.dm-page-header[_ngcontent-%COMP%]{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap}.dm-page-header[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:0}.dm-sep[_ngcontent-%COMP%]{color:var(--mat-sys-outline)}.dm-app[_ngcontent-%COMP%]{color:var(--mat-sys-primary);font-weight:500}.dm-back[_ngcontent-%COMP%]{display:inline-flex;align-items:center;justify-content:center;color:var(--mat-sys-on-surface-variant);text-decoration:none;padding:4px;border-radius:8px}.dm-back[_ngcontent-%COMP%]:hover{background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface)}.dm-page-sub[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant);margin-top:.25rem;font-size:.875rem}.dm-paused[_ngcontent-%COMP%]{color:var(--mat-sys-tertiary)}.dm-header-actions[_ngcontent-%COMP%]{display:flex;gap:.5rem}.dm-toolbar[_ngcontent-%COMP%]{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin:1rem 0}.dm-since[_ngcontent-%COMP%]{width:8rem}.dm-path-filter[_ngcontent-%COMP%]{flex:1;min-width:14rem}.dm-chip-group[_ngcontent-%COMP%]{display:inline-flex;align-items:center;gap:.35rem;flex-wrap:wrap}.dm-chip-label[_ngcontent-%COMP%]{font:500 .6875rem/1rem Roboto;text-transform:uppercase;letter-spacing:.04rem;color:var(--mat-sys-on-surface-variant);margin-right:.25rem}.dm-chip[_ngcontent-%COMP%]{font-family:Roboto Mono,ui-monospace,monospace;font-size:.75rem;padding:4px 10px;border-radius:999px;border:1px solid var(--mat-sys-outline-variant);background:var(--mat-sys-surface-container);color:var(--mat-sys-on-surface-variant);cursor:pointer;letter-spacing:.04rem}.dm-chip[_ngcontent-%COMP%]:hover{color:var(--mat-sys-on-surface)}.dm-chip-active[_ngcontent-%COMP%]{background:color-mix(in oklch,var(--mat-sys-primary) 14%,transparent);border-color:color-mix(in oklch,var(--mat-sys-primary) 35%,transparent);color:var(--mat-sys-primary)}.dm-skel-rows[_ngcontent-%COMP%]{display:flex;flex-direction:column;gap:.35rem}.dm-table-wrap[_ngcontent-%COMP%]{border:1px solid var(--mat-sys-outline-variant);border-radius:12px;overflow:hidden;background:var(--mat-sys-surface-container-lowest)}.dm-req-table[_ngcontent-%COMP%]{width:100%;border-collapse:collapse;table-layout:fixed}.dm-req-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%]{text-align:left;padding:8px 12px;font:500 .6875rem/1rem Roboto;text-transform:uppercase;letter-spacing:.04rem;color:var(--mat-sys-on-surface-variant);background:var(--mat-sys-surface-container);border-bottom:1px solid var(--mat-sys-outline-variant)}.dm-req-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{padding:6px 12px;border-bottom:1px solid var(--mat-sys-outline-variant);font-size:.8125rem;height:32px;line-height:20px;vertical-align:middle;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dm-req-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%]{border-bottom:none}.dm-req-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover{background:color-mix(in oklch,var(--mat-sys-primary) 6%,transparent)}.dm-col-time[_ngcontent-%COMP%]{width:7rem}.dm-col-method[_ngcontent-%COMP%], .dm-col-status[_ngcontent-%COMP%]{width:5rem}.dm-col-path[_ngcontent-%COMP%]{width:auto}.dm-col-dur[_ngcontent-%COMP%]{width:5rem;text-align:right}.dm-method[data-method=GET][_ngcontent-%COMP%]{color:var(--mat-sys-primary)}.dm-method[data-method=POST][_ngcontent-%COMP%]{color:var(--mat-sys-tertiary)}.dm-method[data-method=DELETE][_ngcontent-%COMP%]{color:var(--mat-sys-error)}.dm-method[data-method=PUT][_ngcontent-%COMP%], .dm-method[data-method=PATCH][_ngcontent-%COMP%]{color:var(--mat-sys-secondary)}.dm-method[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant)}.dm-status[data-bucket="2xx"][_ngcontent-%COMP%]{color:var(--mat-sys-primary)}.dm-status[data-bucket="3xx"][_ngcontent-%COMP%]{color:var(--mat-sys-secondary)}.dm-status[data-bucket="4xx"][_ngcontent-%COMP%]{color:var(--mat-sys-tertiary)}.dm-status[data-bucket="5xx"][_ngcontent-%COMP%]{color:var(--mat-sys-error)}.dm-status[_ngcontent-%COMP%]{color:var(--mat-sys-on-surface-variant)}.dm-path[_ngcontent-%COMP%]{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;color:var(--mat-sys-on-surface)}.dm-empty-link[_ngcontent-%COMP%]{color:var(--mat-sys-primary);text-decoration:none;margin-top:.5rem}.dm-empty-link[_ngcontent-%COMP%]:hover{text-decoration:underline}'],changeDetection:0})};export{pe as RequestsPageComponent};