denvig 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,33 +1,33 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Gr=Object.create;var ut=Object.defineProperty;var qr=Object.getOwnPropertyDescriptor;var zr=Object.getOwnPropertyNames;var Hr=Object.getPrototypeOf,Ur=Object.prototype.hasOwnProperty;var f=(t,e)=>()=>(t&&(e=t(t=0)),e);var x=(t,e)=>{for(var s in e)ut(t,s,{get:e[s],enumerable:!0})},Br=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of zr(e))!Ur.call(t,r)&&r!==s&&ut(t,r,{get:()=>e[r],enumerable:!(n=qr(e,r))||n.enumerable});return t};var I=(t,e,s)=>(s=t!=null?Gr(Hr(t)):{},Br(e||!t||!t.__esModule?ut(s,"default",{value:t,enumerable:!0}):s,t));var $s,Cs=f(()=>{$s={name:"denvig",version:"0.5.0",license:"MIT",description:"A CLI tool to consistently manage cross-discipline projects",bin:{denvig:"./dist/cli.cjs"},type:"module",main:"./dist/sdk.cjs",module:"./dist/sdk.js",types:"./dist/sdk.d.ts",exports:{".":{import:{types:"./dist/sdk.d.ts",default:"./dist/sdk.js"},require:{types:"./dist/sdk.d.ts",default:"./dist/sdk.cjs"}}},files:["dist/","LICENSE","README.md"],scripts:{build:"rm -rf dist && tsup","check-types":"tsc --noEmit",codegen:"bin/codegen",prepublishOnly:"npm run build",lint:"biome check","lint:fix":"biome check --fix",test:"node --test --test-skip-pattern='node_modules' 'src/**/*.test.ts'","test:ci":"node --test --test-skip-pattern='node_modules' 'src/**/*.test.ts' --reporter=default",dev:"tsc --watch"},dependencies:{minimist:"^1.2.8",semver:"^7.7.3",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"^2.3.12","@types/minimist":"^1.2.5","@types/node":"^24","@types/semver":"^7.7.1",tsup:"^8.5.1",typescript:"^5.9.3"},engines:{node:">=22"},repository:{type:"git",url:"git+https://github.com/marcqualie/denvig.git"},keywords:["cli","node","developer-tools","productivity","typescript"]}});function z(){return $s.version}var ke=f(()=>{"use strict";Cs()});var S,so,Ls,Ge,dt=f(()=>{"use strict";S=require("zod"),so=["build","check-types","dev","install","lint","outdated","test"],Ls=S.z.object({projectPaths:S.z.array(S.z.string()).optional().default(["~/src/*/*","~/.dotfiles"]).describe("Paths or patterns where projects are located"),quickActions:S.z.array(S.z.string()).default(so).optional().describe("Quick actions that are available for all projects")}),Ge=S.z.object({name:S.z.string().optional().describe("Display name for the project"),actions:S.z.record(S.z.string().describe("Name of the action"),S.z.object({command:S.z.string().describe("Shell command to run for the action")})).optional().describe("Actions that can be run against the project"),quickActions:S.z.array(S.z.string()).optional().describe("Actions that are available on the CLI root for quick access"),services:S.z.record(S.z.string().max(64,"Service name must be 64 characters or less").regex(/^[a-z]([a-z0-9-]*[a-z0-9])?$/,"Service name must start with a letter, contain only lowercase alphanumeric and hyphens, and not end with a hyphen"),S.z.object({cwd:S.z.string().optional().describe("Working directory for the service (relative to project root)"),command:S.z.string().describe("Shell command to execute"),http:S.z.object({port:S.z.number().optional().describe("Port number the service listens on"),domain:S.z.string().optional().describe("Domain to use for the service URL"),secure:S.z.boolean().optional().describe("Use HTTPS instead of HTTP")}).strict().optional().describe("HTTP configuration for the service URL"),envFiles:S.z.array(S.z.string()).optional().describe("Paths to .env files (relative to service cwd)"),env:S.z.record(S.z.string(),S.z.string()).optional().describe("Environment variables"),keepAlive:S.z.boolean().optional().describe("Restart service if it exits"),startOnBoot:S.z.boolean().optional().describe("Start service automatically when system boots")}).strict()).optional().describe("Service that can be managed for this project")}).strict()});var Rs,no,Oe,gt=f(()=>{"use strict";Rs=require("fs"),no=require("fs/promises"),Oe=t=>{try{return(0,Rs.readFileSync)(t,"utf8").trim()||null}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")return null;throw e}}});var ft,ht,ro,oo,oe,io,ie,Is,ce=f(()=>{"use strict";ft=require("path"),ht=require("yaml");dt();gt();ro=(0,ft.resolve)(`${process.env.HOME}/.denvig/config.yml`),oo={projectPaths:["~/src/*/*","~/.dotfiles"],quickActions:void 0},oe=t=>t.startsWith("~/")?`${process.env.HOME}${t.slice(1)}`:t,io=()=>{let t={},e=process.env.DENVIG_PROJECT_PATHS;e!==void 0&&(t.projectPaths=e.split(",").map(n=>n.trim()).filter(n=>n.length>0));let s=process.env.DENVIG_QUICK_ACTIONS;return s!==void 0&&(s===""?t.quickActions=[]:t.quickActions=s.split(",").map(n=>n.trim()).filter(n=>n.length>0)),t},ie=()=>{let t=[],e={},s=process.env.DENVIG_GLOBAL_CONFIG_PATH,n=s?(0,ft.resolve)(s):ro,r=Oe(n);if(r)try{let a=(0,ht.parse)(r)||{};e={...e,...a},t.push(n)}catch(a){console.error(`Error parsing global config at ${n}:`,a),process.exit(1)}let o=io();return e={...e,...o},{...Ls.parse({...oo,...e}),$sources:t}},Is=t=>{let e=`${t}/.denvig.yml`,s=Oe(e);if(s)try{return{...Ge.parse((0,ht.parse)(s)),$sources:[e]}}catch{}return{$sources:[]}}});var vt,Ts,co,yt,qe,ze=f(()=>{"use strict";vt=I(require("fs"),1),Ts=I(require("path"),1),co=t=>{let e=t.match(/^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);if(e)return`${e[1]}/${e[2]}`;let s=t.match(/^https:\/\/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);return s?`${s[1]}/${s[2]}`:null},yt=t=>{let e=Ts.default.join(t,".git","config");if(!vt.default.existsSync(e))return null;try{let n=vt.default.readFileSync(e,"utf-8").match(/\[remote "origin"\][^[]*url\s*=\s*([^\s\n]+)/);if(n){let r=n[1];return co(r)}return null}catch{return null}},qe=t=>{let e=yt(t);return e?`github:${e}`:`local:${t}`}});var He,bt=f(()=>{"use strict";He=(t,e)=>{for(let[s,n]of Object.entries(e))t[s]||(t[s]=[]),t[s].push(...n);return t}});var jt,U,Ne=f(()=>{"use strict";jt=I(require("fs"),1),U=t=>{let e=`${t.path}/package.json`;if(!jt.default.existsSync(e))return null;let s=jt.default.readFileSync(e,"utf-8");return JSON.parse(s)}});var _,ee=f(()=>{"use strict";_=t=>t});var B,ao,As,Fs=f(()=>{"use strict";B=I(require("fs"),1);bt();Ne();ee();ao=_({name:"deno",actions:async t=>{let e=B.default.readdirSync(t.path);if(!(e.includes("deno.json")||e.includes("deno.jsonc")))return{};let r=U(t)?.scripts||{},o={...Object.entries(r).map(([l,c])=>[l,`deno ${c}`]).reduce((l,[c,p])=>(l[c]=[p],l),{}),install:["deno install"],outdated:["deno outdated"]},i=((0,B.existsSync)(`${t.path}/deno.json`)?JSON.parse((0,B.readFileSync)(`${t.path}/deno.json`,"utf8")):(0,B.existsSync)(`${t.path}/deno.jsonc`)?JSON.parse((0,B.readFileSync)(`${t.path}/deno.jsonc`,"utf8")):{}).tasks||{};return o=He(o,{test:[i?.test?"deno task test":"deno test"],lint:[i?.lint?"deno task lint":"deno lint"],"check-types":[i?.checkTypes?"deno task check-types":"deno check"],...Object.entries(i).reduce((l,[c,p])=>(l[c]=[p.startsWith("deno")?p:`deno task ${c}`],l),{}),install:["deno install"],outdated:["deno outdated"]}),o}}),As=ao});var _s,lo,Es,Ws=f(()=>{"use strict";_s=I(require("fs"),1);Ne();ee();lo=_({name:"npm",actions:async t=>{let e=_s.default.readdirSync(t.path),s=e.includes("package.json"),n=e.includes("package-lock.json");if(!(s&&n))return{};let a=U(t)?.scripts||{};return{...Object.entries(a).map(([l,c])=>[l,`npm run ${l}`]).reduce((l,[c,p])=>(l[c]=[p],l),{}),install:["npm install"],outdated:["npm outdated"]}}}),Es=lo});var E,Ms,po,uo,mo,Vs,go,fo,ho,Js,Gs=f(()=>{"use strict";E=require("fs"),Ms=require("os"),po=3600*1e3,uo=()=>{let t=`${(0,Ms.homedir)()}/.cache/denvig/dependencies/npm`;return(0,E.existsSync)(t)||(0,E.mkdirSync)(t,{recursive:!0}),t},mo=t=>{let e=t.replace(/@/g,"_at_").replace(/\//g,"__");return e=e.replace(/[^a-zA-Z0-9\-_.]/g,"_"),e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},Vs=t=>{let e=mo(t);return`${uo()}/${e}.json`},go=t=>{try{let e=(0,E.statSync)(t);return Date.now()-e.mtimeMs<po}catch{return!1}},fo=t=>{let e=Vs(t);if(!(0,E.existsSync)(e)||!go(e))return null;try{let s=(0,E.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},ho=(t,e)=>{try{let s=Vs(t);(0,E.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},Js=async(t,e=!1)=>{if(!e){let s=fo(t);if(s)return s}try{let s=await fetch(`https://registry.npmjs.com/${encodeURIComponent(t)}`,{headers:{Accept:"application/json"}});if(!s.ok)return null;let n=await s.json(),r=Object.keys(n.versions),o=n["dist-tags"]?.latest||r[r.length-1],a={versions:r,latest:o};return ho(t,a),a}catch{return null}}});var ae,Ue,vo,yo,bo,Be,Pt=f(()=>{"use strict";Gs();ae=t=>{let e=t.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:Number.parseInt(e[3],10),prerelease:e[4]||""}:null},Ue=(t,e)=>{let s=ae(t),n=ae(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},vo=(t,e)=>{let s=ae(t);if(!s||s.prerelease)return!1;if(e.startsWith("^")){let r=ae(e.slice(1));return r?r.major===0?s.major===0&&s.minor===r.minor&&s.patch>=r.patch:s.major===r.major&&Ue(t,e.slice(1))>=0:!1}if(e.startsWith("~")){let r=ae(e.slice(1));return r?s.major===r.major&&s.minor===r.minor&&s.patch>=r.patch:!1}if(e.startsWith(">="))return Ue(t,e.slice(2))>=0;if(e.startsWith(">")&&!e.startsWith(">="))return Ue(t,e.slice(1))>0;let n=ae(e);return n?s.major===n.major&&s.minor===n.minor&&s.patch===n.patch:!1},yo=(t,e)=>{let s=t.filter(n=>vo(n,e)).sort(Ue);return s.length>0?s[s.length-1]:null},bo=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},Be=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=bo(a);if(!i)return;let l=await Js(a.name,!s);if(!l)return;let c=yo(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var Le,zs,qs,St,Hs,Us,Bs=f(()=>{"use strict";Le=require("fs"),zs=require("yaml");Pt();Ne();ee();qs=new Map,St=t=>{let e=t.indexOf("(");return e===-1?t:t.slice(0,e)},Hs=_({name:"pnpm",actions:async t=>{if(!t.rootFiles.includes("pnpm-lock.yaml"))return{};let r=U(t)?.scripts||{},o=t.rootFiles.includes("pnpm-workspace.yaml");return{...Object.entries(r).map(([i,l])=>[i,`pnpm run ${i}`]).reduce((i,[l,c])=>(i[l]=[c],i),{}),install:["pnpm install"],outdated:[o?"pnpm outdated -r":"pnpm outdated"]}},dependencies:async t=>{if(!(0,Le.existsSync)(`${t.path}/pnpm-lock.yaml`))return[];let e=qs.get(t.path);if(e)return e;let s=new Map,n=new Set,r=(c,p,d,u,m,v)=>{let g=s.get(c);g?g.versions.push({resolved:u,specifier:v,source:m}):s.set(c,{id:c,name:p,ecosystem:d,versions:[{resolved:u,specifier:v,source:m}]})};s.set("npm:pnpm",{id:"npm:pnpm",name:"pnpm",ecosystem:"system",versions:[]});let o=`${t.path}/pnpm-lock.yaml`,a=(0,Le.readFileSync)(o,"utf-8"),i=(0,zs.parse)(a);if(i?.importers)for(let[c,p]of Object.entries(i.importers)){let d=c==="."?".":c;if(p.dependencies)for(let[u,m]of Object.entries(p.dependencies))m?.specifier&&m?.version&&(n.add(u),r(`npm:${u}`,u,"npm",St(m.version),`${d}#dependencies`,m.specifier));if(p.devDependencies)for(let[u,m]of Object.entries(p.devDependencies))m?.specifier&&m?.version&&(n.add(u),r(`npm:${u}`,u,"npm",St(m.version),`${d}#devDependencies`,m.specifier))}if(i?.snapshots)for(let[c,p]of Object.entries(i.snapshots)){let d={...p.dependencies};for(let[u,m]of Object.entries(d))if(!n.has(u)){let v=St(m),g=`pnpm-lock.yaml:${c}`;r(`npm:${u}`,u,"npm",v,g,v)}}let l=Array.from(s.values()).sort((c,p)=>c.name.localeCompare(p.name));return qs.set(t.path,l),l},outdatedDependencies:async(t,e)=>{if(!(0,Le.existsSync)(`${t.path}/pnpm-lock.yaml`))return[];let s=await Hs.dependencies?.(t);return s?Be(s,e):[]}}),Us=Hs});var W,Ys,jo,Po,So,Ks,Do,wo,Co,Zs,Qs=f(()=>{"use strict";W=require("fs"),Ys=require("os"),jo=3600*1e3,Po=()=>{let t=`${(0,Ys.homedir)()}/.cache/denvig/dependencies/rubygems`;return(0,W.existsSync)(t)||(0,W.mkdirSync)(t,{recursive:!0}),t},So=t=>{let e=t.replace(/[^a-zA-Z0-9\-_.]/g,"_");return e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},Ks=t=>{let e=So(t);return`${Po()}/${e}.json`},Do=t=>{try{let e=(0,W.statSync)(t);return Date.now()-e.mtimeMs<jo}catch{return!1}},wo=t=>{let e=Ks(t);if(!(0,W.existsSync)(e)||!Do(e))return null;try{let s=(0,W.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},Co=(t,e)=>{try{let s=Ks(t);(0,W.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},Zs=async(t,e=!1)=>{if(!e){let s=wo(t);if(s)return s}try{let s=await fetch(`https://rubygems.org/api/v1/versions/${encodeURIComponent(t)}.json`,{headers:{Accept:"application/json"}});if(!s.ok)return null;let n=await s.json(),r=n.map(l=>l.number),a=n.filter(l=>!l.prerelease).map(l=>l.number)[0]||r[0],i={versions:r,latest:a};return Co(t,i),i}catch{return null}}});var pe,le,$o,xo,ko,Xs,en=f(()=>{"use strict";Qs();pe=t=>{let e=t.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:-(.+)|\.(.+))?$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:e[3]?Number.parseInt(e[3],10):0,prerelease:e[4]||e[5]||""}:null},le=(t,e)=>{let s=pe(t),n=pe(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},$o=(t,e)=>{let s=pe(t);if(!s||s.prerelease)return!1;if(e==="*")return!0;let n=e.trim();if(n.startsWith("~>")){let o=n.slice(2).trim(),a=pe(o);return a?o.split(".").length>=3?s.major===a.major&&s.minor===a.minor&&s.patch>=a.patch:s.major===a.major&&s.minor>=a.minor&&le(t,`${a.major}.${a.minor}.0`)>=0:!1}if(n.startsWith(">="))return le(t,n.slice(2).trim())>=0;if(n.startsWith(">")&&!n.startsWith(">="))return le(t,n.slice(1).trim())>0;if(n.startsWith("<="))return le(t,n.slice(2).trim())<=0;if(n.startsWith("<")&&!n.startsWith("<="))return le(t,n.slice(1).trim())<0;if(n.startsWith("=")){let o=n.slice(1).trim(),a=pe(o);return a?s.major===a.major&&s.minor===a.minor&&s.patch===a.patch:!1}let r=pe(n);return r?s.major===r.major&&s.minor===r.minor&&s.patch===r.patch:!1},xo=(t,e)=>{let s=t.filter(n=>$o(n,e)).sort(le);return s.length>0?s[s.length-1]:null},ko=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},Xs=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=ko(a);if(!i)return;let l=await Zs(a.name,!s);if(!l)return;let c=xo(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var ue,Oo,No,tn,sn=f(()=>{"use strict";ue=require("fs"),Oo=t=>{let e=[],s=t.split(`
3
- `),n="dependencies",r=0;for(let o of s){let a=o.trim();if(a.startsWith("#")||a==="")continue;if(a.startsWith("group ")){(a.includes(":development")||a.includes(":test"))&&(n="devDependencies"),a.includes(" do")&&r++;continue}if(a==="end"){r--,r<=0&&(n="dependencies",r=0);continue}let i=a.match(/^gem\s+['"]([^'"]+)['"](?:\s*,\s*['"]([^'"]+)['"])?/);if(i){let l=i[1],c=i[2]||"*";e.push({name:l,specifier:c,group:n})}}return e},No=t=>{let e={},s={},n=t.split(`
4
- `),r="none",o=null,a=null;for(let i of n){let l=i.trimEnd();if(l==="GEM"){r="gem";continue}if(l==="PLATFORMS"){r="platforms";continue}if(l==="DEPENDENCIES"){r="dependencies";continue}if(l==="BUNDLED WITH"){r="none";continue}if(r==="gem"&&l===" specs:"){r="specs";continue}if(r==="specs"){if(l==="")continue;let c=i.match(/^(\s*)/),p=c?c[1].length:0,d=i.trim();if(p===4){let u=d.match(/^([^\s(]+)\s+\(([^)]+)\)/);if(u){let m=u[2],v=m.match(/^[\d.]+/),g=v?v[0]:m;o=u[1],a=g,e[o]||(e[o]={version:g,dependencies:{}})}}else if(p===6&&o&&a){let u=d.match(/^([^\s(]+)(?:\s+\(([^)]+)\))?/);if(u){let m=u[1],v=u[2]||"*";e[o].dependencies[m]=v}}}if(r==="dependencies"){if(l===""||l.startsWith(" ")===!1)continue;let c=l.match(/^\s+([^\s(!]+)(?:\s+\(([^)]+)\))?/);if(c){let d=c[1].replace(/!$/,""),u=c[2]||"*";s[d]=u}}}return{specs:e,dependencies:s}},tn=async t=>{let e=`${t.path}/Gemfile`,s=`${t.path}/Gemfile.lock`;if(!(0,ue.existsSync)(e))return[];let n=new Map,r=new Set,o=(0,ue.readFileSync)(e,"utf-8"),a=Oo(o),i=(l,c,p,d,u,m)=>{let v=n.get(l);v?v.versions.push({resolved:d,specifier:m,source:u}):n.set(l,{id:l,name:c,ecosystem:p,versions:[{resolved:d,specifier:m,source:u}]})};n.set("rubygems:bundler",{id:"rubygems:bundler",name:"bundler",ecosystem:"system",versions:[]});for(let l of a)r.add(l.name);if((0,ue.existsSync)(s)){let l=(0,ue.readFileSync)(s,"utf-8"),c=No(l);for(let p of a){let d=c.specs[p.name];d&&i(`rubygems:${p.name}`,p.name,"rubygems",d.version,`.#${p.group}`,p.specifier)}for(let[p,d]of Object.entries(c.specs))if(!r.has(p)){for(let[u,m]of Object.entries(c.specs))if(m.dependencies[p]){let v=`Gemfile.lock:${u}@${m.version}`,g=m.dependencies[p];i(`rubygems:${p}`,p,"rubygems",d.version,v,g)}}}else for(let l of a)i(`rubygems:${l.name}`,l.name,"rubygems",l.specifier,`.#${l.group}`,l.specifier);return Array.from(n.values()).sort((l,c)=>l.name.localeCompare(c.name))}});var Dt,nn,rn,on,cn=f(()=>{"use strict";Dt=I(require("fs"),1);ee();en();sn();nn=new Map,rn=_({name:"ruby",actions:async t=>{let e=Dt.default.readdirSync(t.path),s=e.includes("Gemfile"),n=e.includes("Rakefile"),r=e.includes("config.ru"),o=Dt.default.existsSync(`${t.path}/config/application.rb`);if(!(s||n))return{};let i={install:["bundle install"],update:["bundle update"],outdated:["bundle outdated"]};return o&&(i.dev=["bundle exec rails server"],i.repl=["bundle exec rails console"]),r&&!o&&(i.dev=["bundle exec rackup"]),i},dependencies:async t=>{if(!t.rootFiles.includes("Gemfile"))return[];let s=nn.get(t.path);if(s)return s;let n=await tn(t);return nn.set(t.path,n),n},outdatedDependencies:async(t,e)=>{if(!t.rootFiles.includes("Gemfile"))return[];let n=await rn.dependencies?.(t);return n?Xs(n,e):[]}}),on=rn});var M,an,Lo,Ro,Io,ln,To,Ao,Fo,pn,un=f(()=>{"use strict";M=require("fs"),an=require("os"),Lo=3600*1e3,Ro=()=>{let t=`${(0,an.homedir)()}/.cache/denvig/dependencies/pypi`;return(0,M.existsSync)(t)||(0,M.mkdirSync)(t,{recursive:!0}),t},Io=t=>{let e=t.toLowerCase().replace(/[-_.]+/g,"-");return e=e.replace(/[^a-zA-Z0-9-]/g,"_"),e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},ln=t=>{let e=Io(t);return`${Ro()}/${e}.json`},To=t=>{try{let e=(0,M.statSync)(t);return Date.now()-e.mtimeMs<Lo}catch{return!1}},Ao=t=>{let e=ln(t);if(!(0,M.existsSync)(e)||!To(e))return null;try{let s=(0,M.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},Fo=(t,e)=>{try{let s=ln(t);(0,M.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},pn=async(t,e=!1)=>{let s=t.toLowerCase().replace(/_/g,"-");if(!e){let n=Ao(s);if(n)return n}try{let n=await fetch(`https://pypi.org/pypi/${encodeURIComponent(s)}/json`,{headers:{Accept:"application/json"}});if(!n.ok)return null;let r=await n.json(),o=Object.entries(r.releases).filter(([,l])=>l.length>0).map(([l])=>l),a=r.info?.version||o[o.length-1],i={versions:o,latest:a};return Fo(s,i),i}catch{return null}}});var de,me,_o,Eo,Wo,Mo,mn,dn=f(()=>{"use strict";un();de=t=>{let e=t.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:\.(\d+))?(.*)$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:e[3]?Number.parseInt(e[3],10):0,prerelease:e[5]||""}:null},me=(t,e)=>{let s=de(t),n=de(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},_o=t=>/[a-zA-Z]/.test(t),Eo=(t,e)=>{let s=de(t);if(!s||_o(t))return!1;if(e==="*")return!0;if(e.startsWith("~=")){let r=e.slice(2).trim(),o=de(r);return o?r.split(".").length>=3?s.major===o.major&&s.minor===o.minor&&s.patch>=o.patch:s.major===o.major&&s.minor>=o.minor:!1}if(e.startsWith(">="))return me(t,e.slice(2).trim())>=0;if(e.startsWith(">")&&!e.startsWith(">="))return me(t,e.slice(1).trim())>0;if(e.startsWith("<="))return me(t,e.slice(2).trim())<=0;if(e.startsWith("<")&&!e.startsWith("<="))return me(t,e.slice(1).trim())<0;if(e.startsWith("!="))return me(t,e.slice(2).trim())!==0;if(e.startsWith("==")){let r=e.slice(2).trim();if(r.endsWith(".*")){let a=r.slice(0,-2);return t.startsWith(a)}let o=de(r);return o?s.major===o.major&&s.minor===o.minor&&s.patch===o.patch:!1}let n=de(e);return n?s.major===n.major&&s.minor===n.minor&&s.patch===n.patch:!1},Wo=(t,e)=>{let s=t.filter(n=>Eo(n,e)).sort(me);return s.length>0?s[s.length-1]:null},Mo=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},mn=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=Mo(a);if(!i)return;let l=await pn(a.name,!s);if(!l)return;let c=Wo(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var Vo,wt,Ct,Ke,gn,Ye,$t,fn=f(()=>{"use strict";Vo=t=>{let e=t.trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e},wt=t=>{let e=t.trim();return e==="true"?!0:e==="false"?!1:/^-?\d+$/.test(e)?Number.parseInt(e,10):/^-?\d+\.\d+$/.test(e)?Number.parseFloat(e):Vo(e)},Ct=t=>{let e={},s=t.slice(1,-1).trim();if(!s)return e;let n=[],r="",o=0,a=!1,i="";for(let l=0;l<s.length;l++){let c=s[l];if(!a&&(c==='"'||c==="'")?(a=!0,i=c):a&&c===i&&s[l-1]!=="\\"&&(a=!1),!a){if(c==="{"||c==="[")o++;else if(c==="}"||c==="]")o--;else if(c===","&&o===0){n.push(r.trim()),r="";continue}}r+=c}r.trim()&&n.push(r.trim());for(let l of n){let c=l.indexOf("=");if(c===-1)continue;let p=l.slice(0,c).trim(),d=l.slice(c+1).trim();d.startsWith("{")?e[p]=Ct(d):d.startsWith("[")?e[p]=Ke(d):e[p]=wt(d)}return e},Ke=t=>{let e=[],s=t.slice(1,-1).trim();if(!s)return e;let n=[],r="",o=0,a=!1,i="";for(let l=0;l<s.length;l++){let c=s[l];if(!a&&(c==='"'||c==="'")?(a=!0,i=c):a&&c===i&&s[l-1]!=="\\"&&(a=!1),!a){if(c==="{"||c==="[")o++;else if(c==="}"||c==="]")o--;else if(c===","&&o===0){n.push(r.trim()),r="";continue}}r+=c}r.trim()&&n.push(r.trim());for(let l of n){let c=l.trim();c.startsWith("{")?e.push(Ct(c)):c.startsWith("[")?e.push(Ke(c)):e.push(wt(c))}return e},gn=(t,e,s)=>{let n=t;for(let r=0;r<e.length-1;r++){let o=e[r];(!(o in n)||typeof n[o]!="object")&&(n[o]={}),n=n[o]}n[e[e.length-1]]=s},Ye=(t,e)=>{let s=t;for(let n of e)(!(n in s)||typeof s[n]!="object")&&(s[n]={}),s=s[n];return s},$t=t=>{let e={},s=t.split(`
5
- `),n=[],r=null,o=null,a=null,i=null;for(let l=0;l<s.length;l++){let c=s[l];if(a!==null&&i!==null){if(a+=c,c.includes("]")){let g=0,y=-1;for(let j=0;j<a.length;j++)if(a[j]==="[")g++;else if(a[j]==="]"&&(g--,g===0)){y=j;break}if(y!==-1){let j=a.slice(0,y+1),P=Ke(j);if(o)o[i]=P;else{let D=[...n,i];gn(e,D,P)}a=null,i=null}}continue}let p=c.indexOf("#");if(p!==-1){let g=!1,y="";for(let j=0;j<p;j++){let P=c[j];!g&&(P==='"'||P==="'")?(g=!0,y=P):g&&P===y&&c[j-1]!=="\\"&&(g=!1)}g||(c=c.slice(0,p))}if(c=c.trim(),!c)continue;if(c.startsWith("[[")&&c.endsWith("]]")){if(o&&r){let g=Ye(e,r.slice(0,-1)),y=r[r.length-1];Array.isArray(g[y])||(g[y]=[]),g[y].push(o)}r=c.slice(2,-2).split("."),o={},n=[];continue}if(c.startsWith("[")&&c.endsWith("]")){if(o&&r){let g=Ye(e,r.slice(0,-1)),y=r[r.length-1];Array.isArray(g[y])||(g[y]=[]),g[y].push(o),o=null,r=null}n=c.slice(1,-1).split("."),Ye(e,n);continue}let d=c.indexOf("=");if(d===-1)continue;let u=c.slice(0,d).trim(),m=c.slice(d+1).trim();if(m.startsWith("[")&&!m.endsWith("]")){a=m,i=u;continue}let v;if(m.startsWith("{")?v=Ct(m):m.startsWith("[")?v=Ke(m):v=wt(m),o)o[u]=v;else{let g=[...n,u];gn(e,g,v)}}if(o&&r){let l=Ye(e,r.slice(0,-1)),c=r[r.length-1];Array.isArray(l[c])||(l[c]=[]),l[c].push(o)}return e}});var ge,Re,xt,Jo,Go,hn,vn=f(()=>{"use strict";ge=require("fs");fn();Re=t=>t.toLowerCase().replace(/_/g,"-"),xt=t=>{let e=t.match(/^([a-zA-Z0-9_-]+(?:\[[^\]]+\])?)(.*)$/);if(e){let s=e[1].replace(/\[.*\]$/,""),n=e[2].trim()||"*";return{name:s,specifier:n}}return{name:t,specifier:"*"}},Jo=t=>{let e=[];try{let s=$t(t);if(s.project?.dependencies)for(let n of s.project.dependencies){let{name:r,specifier:o}=xt(n);e.push({name:r,specifier:o,group:"dependencies"})}if(s.tool?.uv?.["dev-dependencies"])for(let n of s.tool.uv["dev-dependencies"]){let{name:r,specifier:o}=xt(n);e.push({name:r,specifier:o,group:"devDependencies"})}if(s.project?.["optional-dependencies"])for(let n of Object.values(s.project["optional-dependencies"]))for(let r of n){let{name:o,specifier:a}=xt(r);e.push({name:o,specifier:a,group:"devDependencies"})}}catch{}return e},Go=t=>{let e={},s=null;try{let n=$t(t);if(n.package)for(let r of n.package){let o=Re(r.name);r.source?.virtual&&(s=o);let a=r.dependencies?.map(i=>Re(i.name))||[];e[o]={name:r.name,version:r.version,dependencies:a}}}catch{}return{packages:e,projectName:s}},hn=async t=>{let e=`${t.path}/pyproject.toml`,s=`${t.path}/uv.lock`;if(!(0,ge.existsSync)(e))return[];let n=new Map,r=new Set,o=(l,c,p,d,u,m)=>{let v=n.get(l);v?v.versions.push({resolved:d,specifier:m,source:u}):n.set(l,{id:l,name:c,ecosystem:p,versions:[{resolved:d,specifier:m,source:u}]})};n.set("pypi:uv",{id:"pypi:uv",name:"uv",ecosystem:"system",versions:[]});let a=(0,ge.readFileSync)(e,"utf-8"),i=Jo(a);for(let l of i)r.add(Re(l.name));if((0,ge.existsSync)(s)){let l=(0,ge.readFileSync)(s,"utf-8"),c=Go(l);for(let p of i){let d=Re(p.name),u=c.packages[d];u&&o(`pypi:${d}`,u.name,"pypi",u.version,`.#${p.group}`,p.specifier)}for(let[p,d]of Object.entries(c.packages))if(!(p===c.projectName||r.has(p))){for(let[,u]of Object.entries(c.packages))if(u.dependencies.includes(p)){let m=`uv.lock:${u.name}@${u.version}`;o(`pypi:${p}`,d.name,"pypi",d.version,m,"*")}}}else for(let l of i){let c=Re(l.name);o(`pypi:${c}`,l.name,"pypi",l.specifier,`.#${l.group}`,l.specifier)}return Array.from(n.values()).sort((l,c)=>l.name.localeCompare(c.name))}});var bn,yn,jn,Pn,Sn=f(()=>{"use strict";bn=I(require("fs"),1);ee();dn();vn();yn=new Map,jn=_({name:"uv",actions:async t=>{let e=bn.default.readdirSync(t.path),s=e.includes("pyproject.toml");return e.includes("uv.lock")||s?{install:["uv sync"]}:{}},dependencies:async t=>{let e=t.rootFiles.includes("pyproject.toml"),s=t.rootFiles.includes("uv.lock");if(!e&&!s)return[];let n=yn.get(t.path);if(n)return n;let r=await hn(t);return yn.set(t.path,r),r},outdatedDependencies:async(t,e)=>{if(!t.rootFiles.includes("pyproject.toml"))return[];let n=await jn.dependencies?.(t);return n?mn(n,e):[]}}),Pn=jn});var qo,Dn,wn=f(()=>{"use strict";qo=t=>{let e=t.split(`
2
+ "use strict";var qr=Object.create;var mt=Object.defineProperty;var zr=Object.getOwnPropertyDescriptor;var Ur=Object.getOwnPropertyNames;var Hr=Object.getPrototypeOf,Br=Object.prototype.hasOwnProperty;var f=(t,e)=>()=>(t&&(e=t(t=0)),e);var x=(t,e)=>{for(var s in e)mt(t,s,{get:e[s],enumerable:!0})},Yr=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ur(e))!Br.call(t,r)&&r!==s&&mt(t,r,{get:()=>e[r],enumerable:!(n=zr(e,r))||n.enumerable});return t};var I=(t,e,s)=>(s=t!=null?qr(Hr(t)):{},Yr(e||!t||!t.__esModule?mt(s,"default",{value:t,enumerable:!0}):s,t));var xs,$s=f(()=>{xs={name:"denvig",version:"0.5.1",license:"MIT",description:"A CLI tool to consistently manage cross-discipline projects",bin:{denvig:"./dist/cli.cjs"},type:"module",main:"./dist/sdk.cjs",module:"./dist/sdk.js",types:"./dist/sdk.d.ts",exports:{".":{import:{types:"./dist/sdk.d.ts",default:"./dist/sdk.js"},require:{types:"./dist/sdk.d.ts",default:"./dist/sdk.cjs"}}},files:["dist/","LICENSE","README.md"],scripts:{build:"rm -rf dist && tsup","check-types":"tsc --noEmit",codegen:"bin/codegen",prepublishOnly:"npm run build",lint:"biome check","lint:fix":"biome check --fix",test:"node --test --test-skip-pattern='node_modules' 'src/**/*.test.ts'","test:ci":"node --test --test-skip-pattern='node_modules' 'src/**/*.test.ts' --reporter=default",dev:"tsc --watch"},dependencies:{minimist:"^1.2.8",semver:"^7.7.4",yaml:"^2.8.2",zod:"^4.3.6"},devDependencies:{"@biomejs/biome":"^2.3.14","@types/minimist":"^1.2.5","@types/node":"^24","@types/semver":"^7.7.1",tsup:"^8.5.1",typescript:"^5.9.3"},engines:{node:">=22"},repository:{type:"git",url:"git+https://github.com/marcqualie/denvig.git"},keywords:["cli","node","developer-tools","productivity","typescript"]}});function z(){return xs.version}var Oe=f(()=>{"use strict";$s()});var S,no,Rs,qe,gt=f(()=>{"use strict";S=require("zod"),no=["build","check-types","dev","install","lint","outdated","test"],Rs=S.z.object({projectPaths:S.z.array(S.z.string()).optional().default(["~/src/*/*","~/.dotfiles"]).describe("Paths or patterns where projects are located"),quickActions:S.z.array(S.z.string()).default(no).optional().describe("Quick actions that are available for all projects")}),qe=S.z.object({name:S.z.string().optional().describe("Display name for the project"),actions:S.z.record(S.z.string().describe("Name of the action"),S.z.object({command:S.z.string().describe("Shell command to run for the action")})).optional().describe("Actions that can be run against the project"),quickActions:S.z.array(S.z.string()).optional().describe("Actions that are available on the CLI root for quick access"),services:S.z.record(S.z.string().max(64,"Service name must be 64 characters or less").regex(/^[a-z]([a-z0-9-]*[a-z0-9])?$/,"Service name must start with a letter, contain only lowercase alphanumeric and hyphens, and not end with a hyphen"),S.z.object({cwd:S.z.string().optional().describe("Working directory for the service (relative to project root)"),command:S.z.string().describe("Shell command to execute"),http:S.z.object({port:S.z.number().optional().describe("Port number the service listens on"),domain:S.z.string().optional().describe("Domain to use for the service URL"),secure:S.z.boolean().optional().describe("Use HTTPS instead of HTTP")}).optional().describe("HTTP configuration for the service URL"),envFiles:S.z.array(S.z.string()).optional().describe("Paths to .env files (relative to service cwd)"),env:S.z.record(S.z.string(),S.z.string()).optional().describe("Environment variables"),keepAlive:S.z.boolean().optional().describe("Restart service if it exits"),startOnBoot:S.z.boolean().optional().describe("Start service automatically when system boots")})).optional().describe("Service that can be managed for this project")})});var Is,ro,Ne,ft=f(()=>{"use strict";Is=require("fs"),ro=require("fs/promises"),Ne=t=>{try{return(0,Is.readFileSync)(t,"utf8").trim()||null}catch(e){if(e&&typeof e=="object"&&"code"in e&&e.code==="ENOENT")return null;throw e}}});var ht,vt,oo,io,ie,co,ce,Ts,ae=f(()=>{"use strict";ht=require("path"),vt=require("yaml");gt();ft();oo=(0,ht.resolve)(`${process.env.HOME}/.denvig/config.yml`),io={projectPaths:["~/src/*/*","~/.dotfiles"],quickActions:void 0},ie=t=>t.startsWith("~/")?`${process.env.HOME}${t.slice(1)}`:t,co=()=>{let t={},e=process.env.DENVIG_PROJECT_PATHS;e!==void 0&&(t.projectPaths=e.split(",").map(n=>n.trim()).filter(n=>n.length>0));let s=process.env.DENVIG_QUICK_ACTIONS;return s!==void 0&&(s===""?t.quickActions=[]:t.quickActions=s.split(",").map(n=>n.trim()).filter(n=>n.length>0)),t},ce=()=>{let t=[],e={},s=process.env.DENVIG_GLOBAL_CONFIG_PATH,n=s?(0,ht.resolve)(s):oo,r=Ne(n);if(r)try{let a=(0,vt.parse)(r)||{};e={...e,...a},t.push(n)}catch(a){console.error(`Error parsing global config at ${n}:`,a),process.exit(1)}let o=co();return e={...e,...o},{...Rs.parse({...io,...e}),$sources:t}},Ts=t=>{let e=`${t}/.denvig.yml`,s=Ne(e);if(s)try{return{...qe.parse((0,vt.parse)(s)),$sources:[e]}}catch{}return{$sources:[]}}});var yt,As,ao,bt,ze,Ue=f(()=>{"use strict";yt=I(require("fs"),1),As=I(require("path"),1),ao=t=>{let e=t.match(/^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);if(e)return`${e[1]}/${e[2]}`;let s=t.match(/^https:\/\/github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?$/);return s?`${s[1]}/${s[2]}`:null},bt=t=>{let e=As.default.join(t,".git","config");if(!yt.default.existsSync(e))return null;try{let n=yt.default.readFileSync(e,"utf-8").match(/\[remote "origin"\][^[]*url\s*=\s*([^\s\n]+)/);if(n){let r=n[1];return ao(r)}return null}catch{return null}},ze=t=>{let e=bt(t);return e?`github:${e}`:`local:${t}`}});var He,jt=f(()=>{"use strict";He=(t,e)=>{for(let[s,n]of Object.entries(e))t[s]||(t[s]=[]),t[s].push(...n);return t}});var Pt,H,Le=f(()=>{"use strict";Pt=I(require("fs"),1),H=t=>{let e=`${t.path}/package.json`;if(!Pt.default.existsSync(e))return null;let s=Pt.default.readFileSync(e,"utf-8");return JSON.parse(s)}});var _,ee=f(()=>{"use strict";_=t=>t});var B,lo,Fs,_s=f(()=>{"use strict";B=I(require("fs"),1);jt();Le();ee();lo=_({name:"deno",actions:async t=>{let e=B.default.readdirSync(t.path);if(!(e.includes("deno.json")||e.includes("deno.jsonc")))return{};let r=H(t)?.scripts||{},o={...Object.entries(r).map(([l,c])=>[l,`deno ${c}`]).reduce((l,[c,p])=>(l[c]=[p],l),{}),install:["deno install"],outdated:["deno outdated"]},i=((0,B.existsSync)(`${t.path}/deno.json`)?JSON.parse((0,B.readFileSync)(`${t.path}/deno.json`,"utf8")):(0,B.existsSync)(`${t.path}/deno.jsonc`)?JSON.parse((0,B.readFileSync)(`${t.path}/deno.jsonc`,"utf8")):{}).tasks||{};return o=He(o,{test:[i?.test?"deno task test":"deno test"],lint:[i?.lint?"deno task lint":"deno lint"],"check-types":[i?.checkTypes?"deno task check-types":"deno check"],...Object.entries(i).reduce((l,[c,p])=>(l[c]=[p.startsWith("deno")?p:`deno task ${c}`],l),{}),install:["deno install"],outdated:["deno outdated"]}),o}}),Fs=lo});var Es,po,Ws,Ms=f(()=>{"use strict";Es=I(require("fs"),1);Le();ee();po=_({name:"npm",actions:async t=>{let e=Es.default.readdirSync(t.path),s=e.includes("package.json"),n=e.includes("package-lock.json");if(!(s&&n))return{};let a=H(t)?.scripts||{};return{...Object.entries(a).map(([l,c])=>[l,`npm run ${l}`]).reduce((l,[c,p])=>(l[c]=[p],l),{}),install:["npm install"],outdated:["npm outdated"]}}}),Ws=po});var E,Vs,uo,mo,go,Js,fo,ho,vo,Gs,qs=f(()=>{"use strict";E=require("fs"),Vs=require("os"),uo=3600*1e3,mo=()=>{let t=`${(0,Vs.homedir)()}/.cache/denvig/dependencies/npm`;return(0,E.existsSync)(t)||(0,E.mkdirSync)(t,{recursive:!0}),t},go=t=>{let e=t.replace(/@/g,"_at_").replace(/\//g,"__");return e=e.replace(/[^a-zA-Z0-9\-_.]/g,"_"),e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},Js=t=>{let e=go(t);return`${mo()}/${e}.json`},fo=t=>{try{let e=(0,E.statSync)(t);return Date.now()-e.mtimeMs<uo}catch{return!1}},ho=t=>{let e=Js(t);if(!(0,E.existsSync)(e)||!fo(e))return null;try{let s=(0,E.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},vo=(t,e)=>{try{let s=Js(t);(0,E.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},Gs=async(t,e=!1)=>{if(!e){let s=ho(t);if(s)return s}try{let s=await fetch(`https://registry.npmjs.com/${encodeURIComponent(t)}`,{headers:{Accept:"application/json"}});if(!s.ok)return null;let n=await s.json(),r=Object.keys(n.versions),o=n["dist-tags"]?.latest||r[r.length-1],a={versions:r,latest:o};return vo(t,a),a}catch{return null}}});var le,Be,yo,bo,jo,Ye,St=f(()=>{"use strict";qs();le=t=>{let e=t.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:Number.parseInt(e[3],10),prerelease:e[4]||""}:null},Be=(t,e)=>{let s=le(t),n=le(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},yo=(t,e)=>{let s=le(t);if(!s||s.prerelease)return!1;if(e.startsWith("^")){let r=le(e.slice(1));return r?r.major===0?s.major===0&&s.minor===r.minor&&s.patch>=r.patch:s.major===r.major&&Be(t,e.slice(1))>=0:!1}if(e.startsWith("~")){let r=le(e.slice(1));return r?s.major===r.major&&s.minor===r.minor&&s.patch>=r.patch:!1}if(e.startsWith(">="))return Be(t,e.slice(2))>=0;if(e.startsWith(">")&&!e.startsWith(">="))return Be(t,e.slice(1))>0;let n=le(e);return n?s.major===n.major&&s.minor===n.minor&&s.patch===n.patch:!1},bo=(t,e)=>{let s=t.filter(n=>yo(n,e)).sort(Be);return s.length>0?s[s.length-1]:null},jo=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},Ye=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=jo(a);if(!i)return;let l=await Gs(a.name,!s);if(!l)return;let c=bo(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var Re,Us,zs,Dt,Hs,Bs,Ys=f(()=>{"use strict";Re=require("fs"),Us=require("yaml");St();Le();ee();zs=new Map,Dt=t=>{let e=t.indexOf("(");return e===-1?t:t.slice(0,e)},Hs=_({name:"pnpm",actions:async t=>{if(!t.rootFiles.includes("pnpm-lock.yaml"))return{};let r=H(t)?.scripts||{},o=t.rootFiles.includes("pnpm-workspace.yaml");return{...Object.entries(r).map(([i,l])=>[i,`pnpm run ${i}`]).reduce((i,[l,c])=>(i[l]=[c],i),{}),install:["pnpm install"],outdated:[o?"pnpm outdated -r":"pnpm outdated"]}},dependencies:async t=>{if(!(0,Re.existsSync)(`${t.path}/pnpm-lock.yaml`))return[];let e=zs.get(t.path);if(e)return e;let s=new Map,n=new Set,r=(c,p,d,u,m,v)=>{let g=s.get(c);g?g.versions.push({resolved:u,specifier:v,source:m}):s.set(c,{id:c,name:p,ecosystem:d,versions:[{resolved:u,specifier:v,source:m}]})};s.set("npm:pnpm",{id:"npm:pnpm",name:"pnpm",ecosystem:"system",versions:[]});let o=`${t.path}/pnpm-lock.yaml`,a=(0,Re.readFileSync)(o,"utf-8"),i=(0,Us.parse)(a);if(i?.importers)for(let[c,p]of Object.entries(i.importers)){let d=c==="."?".":c;if(p.dependencies)for(let[u,m]of Object.entries(p.dependencies))m?.specifier&&m?.version&&(n.add(u),r(`npm:${u}`,u,"npm",Dt(m.version),`${d}#dependencies`,m.specifier));if(p.devDependencies)for(let[u,m]of Object.entries(p.devDependencies))m?.specifier&&m?.version&&(n.add(u),r(`npm:${u}`,u,"npm",Dt(m.version),`${d}#devDependencies`,m.specifier))}if(i?.snapshots)for(let[c,p]of Object.entries(i.snapshots)){let d={...p.dependencies};for(let[u,m]of Object.entries(d))if(!n.has(u)){let v=Dt(m),g=`pnpm-lock.yaml:${c}`;r(`npm:${u}`,u,"npm",v,g,v)}}let l=Array.from(s.values()).sort((c,p)=>c.name.localeCompare(p.name));return zs.set(t.path,l),l},outdatedDependencies:async(t,e)=>{if(!(0,Re.existsSync)(`${t.path}/pnpm-lock.yaml`))return[];let s=await Hs.dependencies?.(t);return s?Ye(s,e):[]}}),Bs=Hs});var W,Ks,Po,So,Do,Zs,wo,Co,$o,Qs,Xs=f(()=>{"use strict";W=require("fs"),Ks=require("os"),Po=3600*1e3,So=()=>{let t=`${(0,Ks.homedir)()}/.cache/denvig/dependencies/rubygems`;return(0,W.existsSync)(t)||(0,W.mkdirSync)(t,{recursive:!0}),t},Do=t=>{let e=t.replace(/[^a-zA-Z0-9\-_.]/g,"_");return e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},Zs=t=>{let e=Do(t);return`${So()}/${e}.json`},wo=t=>{try{let e=(0,W.statSync)(t);return Date.now()-e.mtimeMs<Po}catch{return!1}},Co=t=>{let e=Zs(t);if(!(0,W.existsSync)(e)||!wo(e))return null;try{let s=(0,W.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},$o=(t,e)=>{try{let s=Zs(t);(0,W.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},Qs=async(t,e=!1)=>{if(!e){let s=Co(t);if(s)return s}try{let s=await fetch(`https://rubygems.org/api/v1/versions/${encodeURIComponent(t)}.json`,{headers:{Accept:"application/json"}});if(!s.ok)return null;let n=await s.json(),r=n.map(l=>l.number),a=n.filter(l=>!l.prerelease).map(l=>l.number)[0]||r[0],i={versions:r,latest:a};return $o(t,i),i}catch{return null}}});var ue,pe,xo,ko,Oo,en,tn=f(()=>{"use strict";Xs();ue=t=>{let e=t.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:-(.+)|\.(.+))?$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:e[3]?Number.parseInt(e[3],10):0,prerelease:e[4]||e[5]||""}:null},pe=(t,e)=>{let s=ue(t),n=ue(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},xo=(t,e)=>{let s=ue(t);if(!s||s.prerelease)return!1;if(e==="*")return!0;let n=e.trim();if(n.startsWith("~>")){let o=n.slice(2).trim(),a=ue(o);return a?o.split(".").length>=3?s.major===a.major&&s.minor===a.minor&&s.patch>=a.patch:s.major===a.major&&s.minor>=a.minor&&pe(t,`${a.major}.${a.minor}.0`)>=0:!1}if(n.startsWith(">="))return pe(t,n.slice(2).trim())>=0;if(n.startsWith(">")&&!n.startsWith(">="))return pe(t,n.slice(1).trim())>0;if(n.startsWith("<="))return pe(t,n.slice(2).trim())<=0;if(n.startsWith("<")&&!n.startsWith("<="))return pe(t,n.slice(1).trim())<0;if(n.startsWith("=")){let o=n.slice(1).trim(),a=ue(o);return a?s.major===a.major&&s.minor===a.minor&&s.patch===a.patch:!1}let r=ue(n);return r?s.major===r.major&&s.minor===r.minor&&s.patch===r.patch:!1},ko=(t,e)=>{let s=t.filter(n=>xo(n,e)).sort(pe);return s.length>0?s[s.length-1]:null},Oo=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},en=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=Oo(a);if(!i)return;let l=await Qs(a.name,!s);if(!l)return;let c=ko(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var me,No,Lo,sn,nn=f(()=>{"use strict";me=require("fs"),No=t=>{let e=[],s=t.split(`
3
+ `),n="dependencies",r=0;for(let o of s){let a=o.trim();if(a.startsWith("#")||a==="")continue;if(a.startsWith("group ")){(a.includes(":development")||a.includes(":test"))&&(n="devDependencies"),a.includes(" do")&&r++;continue}if(a==="end"){r--,r<=0&&(n="dependencies",r=0);continue}let i=a.match(/^gem\s+['"]([^'"]+)['"](?:\s*,\s*['"]([^'"]+)['"])?/);if(i){let l=i[1],c=i[2]||"*";e.push({name:l,specifier:c,group:n})}}return e},Lo=t=>{let e={},s={},n=t.split(`
4
+ `),r="none",o=null,a=null;for(let i of n){let l=i.trimEnd();if(l==="GEM"){r="gem";continue}if(l==="PLATFORMS"){r="platforms";continue}if(l==="DEPENDENCIES"){r="dependencies";continue}if(l==="BUNDLED WITH"){r="none";continue}if(r==="gem"&&l===" specs:"){r="specs";continue}if(r==="specs"){if(l==="")continue;let c=i.match(/^(\s*)/),p=c?c[1].length:0,d=i.trim();if(p===4){let u=d.match(/^([^\s(]+)\s+\(([^)]+)\)/);if(u){let m=u[2],v=m.match(/^[\d.]+/),g=v?v[0]:m;o=u[1],a=g,e[o]||(e[o]={version:g,dependencies:{}})}}else if(p===6&&o&&a){let u=d.match(/^([^\s(]+)(?:\s+\(([^)]+)\))?/);if(u){let m=u[1],v=u[2]||"*";e[o].dependencies[m]=v}}}if(r==="dependencies"){if(l===""||l.startsWith(" ")===!1)continue;let c=l.match(/^\s+([^\s(!]+)(?:\s+\(([^)]+)\))?/);if(c){let d=c[1].replace(/!$/,""),u=c[2]||"*";s[d]=u}}}return{specs:e,dependencies:s}},sn=async t=>{let e=`${t.path}/Gemfile`,s=`${t.path}/Gemfile.lock`;if(!(0,me.existsSync)(e))return[];let n=new Map,r=new Set,o=(0,me.readFileSync)(e,"utf-8"),a=No(o),i=(l,c,p,d,u,m)=>{let v=n.get(l);v?v.versions.push({resolved:d,specifier:m,source:u}):n.set(l,{id:l,name:c,ecosystem:p,versions:[{resolved:d,specifier:m,source:u}]})};n.set("rubygems:bundler",{id:"rubygems:bundler",name:"bundler",ecosystem:"system",versions:[]});for(let l of a)r.add(l.name);if((0,me.existsSync)(s)){let l=(0,me.readFileSync)(s,"utf-8"),c=Lo(l);for(let p of a){let d=c.specs[p.name];d&&i(`rubygems:${p.name}`,p.name,"rubygems",d.version,`.#${p.group}`,p.specifier)}for(let[p,d]of Object.entries(c.specs))if(!r.has(p)){for(let[u,m]of Object.entries(c.specs))if(m.dependencies[p]){let v=`Gemfile.lock:${u}@${m.version}`,g=m.dependencies[p];i(`rubygems:${p}`,p,"rubygems",d.version,v,g)}}}else for(let l of a)i(`rubygems:${l.name}`,l.name,"rubygems",l.specifier,`.#${l.group}`,l.specifier);return Array.from(n.values()).sort((l,c)=>l.name.localeCompare(c.name))}});var wt,rn,on,cn,an=f(()=>{"use strict";wt=I(require("fs"),1);ee();tn();nn();rn=new Map,on=_({name:"ruby",actions:async t=>{let e=wt.default.readdirSync(t.path),s=e.includes("Gemfile"),n=e.includes("Rakefile"),r=e.includes("config.ru"),o=wt.default.existsSync(`${t.path}/config/application.rb`);if(!(s||n))return{};let i={install:["bundle install"],update:["bundle update"],outdated:["bundle outdated"]};return o&&(i.dev=["bundle exec rails server"],i.repl=["bundle exec rails console"]),r&&!o&&(i.dev=["bundle exec rackup"]),i},dependencies:async t=>{if(!t.rootFiles.includes("Gemfile"))return[];let s=rn.get(t.path);if(s)return s;let n=await sn(t);return rn.set(t.path,n),n},outdatedDependencies:async(t,e)=>{if(!t.rootFiles.includes("Gemfile"))return[];let n=await on.dependencies?.(t);return n?en(n,e):[]}}),cn=on});var M,ln,Ro,Io,To,pn,Ao,Fo,_o,un,mn=f(()=>{"use strict";M=require("fs"),ln=require("os"),Ro=3600*1e3,Io=()=>{let t=`${(0,ln.homedir)()}/.cache/denvig/dependencies/pypi`;return(0,M.existsSync)(t)||(0,M.mkdirSync)(t,{recursive:!0}),t},To=t=>{let e=t.toLowerCase().replace(/[-_.]+/g,"-");return e=e.replace(/[^a-zA-Z0-9-]/g,"_"),e=e.replace(/\.{2,}/g,"_"),e=e.replace(/^\.+/,"_"),e.length===0&&(e="_empty_"),e.length>200&&(e=e.slice(0,200)),e},pn=t=>{let e=To(t);return`${Io()}/${e}.json`},Ao=t=>{try{let e=(0,M.statSync)(t);return Date.now()-e.mtimeMs<Ro}catch{return!1}},Fo=t=>{let e=pn(t);if(!(0,M.existsSync)(e)||!Ao(e))return null;try{let s=(0,M.readFileSync)(e,"utf-8");return JSON.parse(s)}catch{return null}},_o=(t,e)=>{try{let s=pn(t);(0,M.writeFileSync)(s,JSON.stringify(e),"utf-8")}catch{}},un=async(t,e=!1)=>{let s=t.toLowerCase().replace(/_/g,"-");if(!e){let n=Fo(s);if(n)return n}try{let n=await fetch(`https://pypi.org/pypi/${encodeURIComponent(s)}/json`,{headers:{Accept:"application/json"}});if(!n.ok)return null;let r=await n.json(),o=Object.entries(r.releases).filter(([,l])=>l.length>0).map(([l])=>l),a=r.info?.version||o[o.length-1],i={versions:o,latest:a};return _o(s,i),i}catch{return null}}});var ge,de,Eo,Wo,Mo,Vo,dn,gn=f(()=>{"use strict";mn();ge=t=>{let e=t.match(/^(\d+)\.(\d+)(?:\.(\d+))?(?:\.(\d+))?(.*)$/);return e?{major:Number.parseInt(e[1],10),minor:Number.parseInt(e[2],10),patch:e[3]?Number.parseInt(e[3],10):0,prerelease:e[5]||""}:null},de=(t,e)=>{let s=ge(t),n=ge(e);return!s||!n?0:s.major!==n.major?s.major-n.major:s.minor!==n.minor?s.minor-n.minor:s.patch!==n.patch?s.patch-n.patch:s.prerelease&&!n.prerelease?-1:!s.prerelease&&n.prerelease?1:0},Eo=t=>/[a-zA-Z]/.test(t),Wo=(t,e)=>{let s=ge(t);if(!s||Eo(t))return!1;if(e==="*")return!0;if(e.startsWith("~=")){let r=e.slice(2).trim(),o=ge(r);return o?r.split(".").length>=3?s.major===o.major&&s.minor===o.minor&&s.patch>=o.patch:s.major===o.major&&s.minor>=o.minor:!1}if(e.startsWith(">="))return de(t,e.slice(2).trim())>=0;if(e.startsWith(">")&&!e.startsWith(">="))return de(t,e.slice(1).trim())>0;if(e.startsWith("<="))return de(t,e.slice(2).trim())<=0;if(e.startsWith("<")&&!e.startsWith("<="))return de(t,e.slice(1).trim())<0;if(e.startsWith("!="))return de(t,e.slice(2).trim())!==0;if(e.startsWith("==")){let r=e.slice(2).trim();if(r.endsWith(".*")){let a=r.slice(0,-2);return t.startsWith(a)}let o=ge(r);return o?s.major===o.major&&s.minor===o.minor&&s.patch===o.patch:!1}let n=ge(e);return n?s.major===n.major&&s.minor===n.minor&&s.patch===n.patch:!1},Mo=(t,e)=>{let s=t.filter(n=>Wo(n,e)).sort(de);return s.length>0?s[s.length-1]:null},Vo=t=>{if(t.versions.length===0)return null;let e=t.versions[0],s=e.source.includes("#devDependencies");return{current:e.resolved,specifier:e.specifier,isDevDependency:s}},dn=async(t,e={})=>{let s=e.cache??!0,n=[],o=t.filter(a=>a.versions.some(i=>i.source.includes("#dependencies")||i.source.includes("#devDependencies"))).map(async a=>{let i=Vo(a);if(!i)return;let l=await un(a.name,!s);if(!l)return;let c=Mo(l.versions,i.specifier),p=l.latest,d=c&&c!==i.current,u=p&&p!==i.current;(d||u)&&n.push({...a,wanted:c||i.current,latest:p,specifier:i.specifier,isDevDependency:i.isDevDependency})});return await Promise.all(o),n}});var Jo,Ct,$t,Ze,fn,Ke,xt,hn=f(()=>{"use strict";Jo=t=>{let e=t.trim();return e.startsWith('"')&&e.endsWith('"')||e.startsWith("'")&&e.endsWith("'")?e.slice(1,-1):e},Ct=t=>{let e=t.trim();return e==="true"?!0:e==="false"?!1:/^-?\d+$/.test(e)?Number.parseInt(e,10):/^-?\d+\.\d+$/.test(e)?Number.parseFloat(e):Jo(e)},$t=t=>{let e={},s=t.slice(1,-1).trim();if(!s)return e;let n=[],r="",o=0,a=!1,i="";for(let l=0;l<s.length;l++){let c=s[l];if(!a&&(c==='"'||c==="'")?(a=!0,i=c):a&&c===i&&s[l-1]!=="\\"&&(a=!1),!a){if(c==="{"||c==="[")o++;else if(c==="}"||c==="]")o--;else if(c===","&&o===0){n.push(r.trim()),r="";continue}}r+=c}r.trim()&&n.push(r.trim());for(let l of n){let c=l.indexOf("=");if(c===-1)continue;let p=l.slice(0,c).trim(),d=l.slice(c+1).trim();d.startsWith("{")?e[p]=$t(d):d.startsWith("[")?e[p]=Ze(d):e[p]=Ct(d)}return e},Ze=t=>{let e=[],s=t.slice(1,-1).trim();if(!s)return e;let n=[],r="",o=0,a=!1,i="";for(let l=0;l<s.length;l++){let c=s[l];if(!a&&(c==='"'||c==="'")?(a=!0,i=c):a&&c===i&&s[l-1]!=="\\"&&(a=!1),!a){if(c==="{"||c==="[")o++;else if(c==="}"||c==="]")o--;else if(c===","&&o===0){n.push(r.trim()),r="";continue}}r+=c}r.trim()&&n.push(r.trim());for(let l of n){let c=l.trim();c.startsWith("{")?e.push($t(c)):c.startsWith("[")?e.push(Ze(c)):e.push(Ct(c))}return e},fn=(t,e,s)=>{let n=t;for(let r=0;r<e.length-1;r++){let o=e[r];(!(o in n)||typeof n[o]!="object")&&(n[o]={}),n=n[o]}n[e[e.length-1]]=s},Ke=(t,e)=>{let s=t;for(let n of e)(!(n in s)||typeof s[n]!="object")&&(s[n]={}),s=s[n];return s},xt=t=>{let e={},s=t.split(`
5
+ `),n=[],r=null,o=null,a=null,i=null;for(let l=0;l<s.length;l++){let c=s[l];if(a!==null&&i!==null){if(a+=c,c.includes("]")){let g=0,y=-1;for(let j=0;j<a.length;j++)if(a[j]==="[")g++;else if(a[j]==="]"&&(g--,g===0)){y=j;break}if(y!==-1){let j=a.slice(0,y+1),P=Ze(j);if(o)o[i]=P;else{let D=[...n,i];fn(e,D,P)}a=null,i=null}}continue}let p=c.indexOf("#");if(p!==-1){let g=!1,y="";for(let j=0;j<p;j++){let P=c[j];!g&&(P==='"'||P==="'")?(g=!0,y=P):g&&P===y&&c[j-1]!=="\\"&&(g=!1)}g||(c=c.slice(0,p))}if(c=c.trim(),!c)continue;if(c.startsWith("[[")&&c.endsWith("]]")){if(o&&r){let g=Ke(e,r.slice(0,-1)),y=r[r.length-1];Array.isArray(g[y])||(g[y]=[]),g[y].push(o)}r=c.slice(2,-2).split("."),o={},n=[];continue}if(c.startsWith("[")&&c.endsWith("]")){if(o&&r){let g=Ke(e,r.slice(0,-1)),y=r[r.length-1];Array.isArray(g[y])||(g[y]=[]),g[y].push(o),o=null,r=null}n=c.slice(1,-1).split("."),Ke(e,n);continue}let d=c.indexOf("=");if(d===-1)continue;let u=c.slice(0,d).trim(),m=c.slice(d+1).trim();if(m.startsWith("[")&&!m.endsWith("]")){a=m,i=u;continue}let v;if(m.startsWith("{")?v=$t(m):m.startsWith("[")?v=Ze(m):v=Ct(m),o)o[u]=v;else{let g=[...n,u];fn(e,g,v)}}if(o&&r){let l=Ke(e,r.slice(0,-1)),c=r[r.length-1];Array.isArray(l[c])||(l[c]=[]),l[c].push(o)}return e}});var fe,Ie,kt,Go,qo,vn,yn=f(()=>{"use strict";fe=require("fs");hn();Ie=t=>t.toLowerCase().replace(/_/g,"-"),kt=t=>{let e=t.match(/^([a-zA-Z0-9_-]+(?:\[[^\]]+\])?)(.*)$/);if(e){let s=e[1].replace(/\[.*\]$/,""),n=e[2].trim()||"*";return{name:s,specifier:n}}return{name:t,specifier:"*"}},Go=t=>{let e=[];try{let s=xt(t);if(s.project?.dependencies)for(let n of s.project.dependencies){let{name:r,specifier:o}=kt(n);e.push({name:r,specifier:o,group:"dependencies"})}if(s.tool?.uv?.["dev-dependencies"])for(let n of s.tool.uv["dev-dependencies"]){let{name:r,specifier:o}=kt(n);e.push({name:r,specifier:o,group:"devDependencies"})}if(s.project?.["optional-dependencies"])for(let n of Object.values(s.project["optional-dependencies"]))for(let r of n){let{name:o,specifier:a}=kt(r);e.push({name:o,specifier:a,group:"devDependencies"})}}catch{}return e},qo=t=>{let e={},s=null;try{let n=xt(t);if(n.package)for(let r of n.package){let o=Ie(r.name);r.source?.virtual&&(s=o);let a=r.dependencies?.map(i=>Ie(i.name))||[];e[o]={name:r.name,version:r.version,dependencies:a}}}catch{}return{packages:e,projectName:s}},vn=async t=>{let e=`${t.path}/pyproject.toml`,s=`${t.path}/uv.lock`;if(!(0,fe.existsSync)(e))return[];let n=new Map,r=new Set,o=(l,c,p,d,u,m)=>{let v=n.get(l);v?v.versions.push({resolved:d,specifier:m,source:u}):n.set(l,{id:l,name:c,ecosystem:p,versions:[{resolved:d,specifier:m,source:u}]})};n.set("pypi:uv",{id:"pypi:uv",name:"uv",ecosystem:"system",versions:[]});let a=(0,fe.readFileSync)(e,"utf-8"),i=Go(a);for(let l of i)r.add(Ie(l.name));if((0,fe.existsSync)(s)){let l=(0,fe.readFileSync)(s,"utf-8"),c=qo(l);for(let p of i){let d=Ie(p.name),u=c.packages[d];u&&o(`pypi:${d}`,u.name,"pypi",u.version,`.#${p.group}`,p.specifier)}for(let[p,d]of Object.entries(c.packages))if(!(p===c.projectName||r.has(p))){for(let[,u]of Object.entries(c.packages))if(u.dependencies.includes(p)){let m=`uv.lock:${u.name}@${u.version}`;o(`pypi:${p}`,d.name,"pypi",d.version,m,"*")}}}else for(let l of i){let c=Ie(l.name);o(`pypi:${c}`,l.name,"pypi",l.specifier,`.#${l.group}`,l.specifier)}return Array.from(n.values()).sort((l,c)=>l.name.localeCompare(c.name))}});var jn,bn,Pn,Sn,Dn=f(()=>{"use strict";jn=I(require("fs"),1);ee();gn();yn();bn=new Map,Pn=_({name:"uv",actions:async t=>{let e=jn.default.readdirSync(t.path),s=e.includes("pyproject.toml");return e.includes("uv.lock")||s?{install:["uv sync"]}:{}},dependencies:async t=>{let e=t.rootFiles.includes("pyproject.toml"),s=t.rootFiles.includes("uv.lock");if(!e&&!s)return[];let n=bn.get(t.path);if(n)return n;let r=await vn(t);return bn.set(t.path,r),r},outdatedDependencies:async(t,e)=>{if(!t.rootFiles.includes("pyproject.toml"))return[];let n=await Pn.dependencies?.(t);return n?dn(n,e):[]}}),Sn=Pn});var zo,wn,Cn=f(()=>{"use strict";zo=t=>{let e=t.split(`
6
6
 
7
7
  `),s={};for(let n of e){let r=n.split(`
8
- `);if(r.length<3)continue;let o=r[0].split(",").map(p=>p.trim().replace(/"|:/g,"")),a=r[1]?.match(/version "(.+)"/)?.[1],i=r[2]?.match(/resolved "(.+)"/)?.[1];if(!a||!i)continue;let l={},c=!1;for(let p=3;p<r.length;p++){let d=r[p];if(d.trim()==="dependencies:"){c=!0;continue}if(c&&d.startsWith(" ")){let u=d.trim().match(/^"?([^"\s]+)"?\s+"?([^"]+)"?$/);u&&(l[u[1]]=u[2])}else c&&!d.startsWith(" ")&&(c=!1)}for(let p of o)p&&(s[p]={version:a,resolved:i,dependencies:Object.keys(l).length>0?l:void 0})}return{type:"success",object:s}},Dn=t=>{let e={},s=qo(t),n=new Map;for(let[r,o]of Object.entries(s.object)){let a=/^(@?.+)@(.+)$/,[,i,l]=r.match(a)||[];i&&(n.has(i)||n.set(i,[]),n.get(i)?.push({version:o.version,specifier:l,deps:o.dependencies}))}for(let[r,o]of n.entries()){e[r]||(e[r]={versions:{}});for(let a of o)e[r].versions[a.version]||(e[r].versions[a.version]={}),e[r].versions[a.version]["yarn.lock"]=a.specifier;e[r].versions=Object.fromEntries(Object.entries(e[r].versions).sort((a,i)=>a[0].localeCompare(i[0],void 0,{numeric:!0})))}for(let[r,o]of n.entries())for(let a of o){if(!a.deps)continue;let i=`${r}@${a.version}`;for(let[l,c]of Object.entries(a.deps)){e[l]||(e[l]={versions:{}});let p=n.get(l);if(!p)continue;let u=p.find(m=>m.specifier===c)?.version||p[0]?.version;if(u){e[l].versions[u]||(e[l].versions[u]={});let m=`yarn.lock:${i}`;e[l].versions[u][m]=c}}}return{dependencies:e}}});function zo(t){return t.includes("__metadata:")}function Ho(t){let e=t.match(/^(.+)@npm:/);if(e)return e[1];let s=t.lastIndexOf("@");return s>0?t.slice(0,s):t}var te,$n,Cn,xn,kn,On=f(()=>{"use strict";te=require("fs"),$n=require("yaml");Pt();Ne();wn();ee();Cn=new Map;xn=_({name:"yarn",actions:async t=>{let e=t.rootFiles.includes("package.json"),s=t.rootFiles.includes("yarn.lock");if(!(e&&s))return{};let o=U(t)?.scripts||{};return{...Object.entries(o).map(([i,l])=>[i,`yarn run ${i}`]).reduce((i,[l,c])=>(i[l]=[c],i),{}),install:["yarn install"],outdated:["yarn outdated"]}},dependencies:async t=>{let e=`${t.path}/yarn.lock`,s=`${t.path}/package.json`;if(!(0,te.existsSync)(e)||!(0,te.existsSync)(s))return[];let n=Cn.get(t.path);if(n)return n;let r=new Map,o=new Set,a=(g,y,j,P,D,$)=>{let V=r.get(g);V?V.versions.push({resolved:P,specifier:$,source:D}):r.set(g,{id:g,name:y,ecosystem:j,versions:[{resolved:P,specifier:$,source:D}]})};r.set("npm:yarn",{id:"npm:yarn",name:"yarn",ecosystem:"system",versions:[]});let i=(0,te.readFileSync)(e,"utf-8"),l=zo(i),c=new Map,p=new Map,d=null;if(l){let g=(0,$n.parse)(i);for(let[y,j]of Object.entries(g)){if(y==="__metadata"||!j?.version||typeof j.version!="string")continue;let P=Ho(y),D=j;c.has(P)||c.set(P,new Map);let $=y.match(/@npm:(.+)$/);$&&c.get(P)?.set($[1],j.version),D.dependencies&&p.set(`${P}@${D.version}`,D.dependencies)}}else{d=Dn(i);for(let[g,y]of Object.entries(d.dependencies)){c.has(g)||c.set(g,new Map);for(let[j,P]of Object.entries(y.versions)){let D=P["yarn.lock"];D&&c.get(g)?.set(D,j)}}}let u=[s],m=t.findFilesByName("package.json");u.push(...m);for(let g of u)try{let y=(0,te.readFileSync)(g,"utf-8"),j=JSON.parse(y),P=".";g!==s&&(P=g.replace(`${t.path}/`,"").replace("/package.json",""));let D=($,V)=>{if($)for(let[q,H]of Object.entries($)){o.add(q);let $e=c.get(q),xe=H;if($e){let Fe=$e.get(H);if(Fe)xe=Fe;else{let _e=$e.values().next().value;_e&&(xe=_e)}}a(`npm:${q}`,q,"npm",xe,`${P}#${V}`,H)}};D(j.dependencies,"dependencies"),D(j.devDependencies,"devDependencies")}catch{}if(l){for(let[g,y]of p.entries())for(let[j,P]of Object.entries(y))if(!o.has(j)){let D=c.get(j),$=P;if(D){let q=D.get(P);if(q)$=q;else{let H=D.values().next().value;H&&($=H)}}let V=`yarn.lock:${g}`;a(`npm:${j}`,j,"npm",$,V,P)}}else if(d){for(let[g,y]of Object.entries(d.dependencies))if(!o.has(g))for(let[j,P]of Object.entries(y.versions))for(let[D,$]of Object.entries(P))D.startsWith("yarn.lock:")&&a(`npm:${g}`,g,"npm",j,D,$)}let v=Array.from(r.values()).sort((g,y)=>g.name.localeCompare(y.name));return Cn.set(t.path,v),v},outdatedDependencies:async(t,e)=>{if(!(0,te.existsSync)(`${t.path}/yarn.lock`))return[];let s=await xn.dependencies?.(t);return s?Be(s,e):[]}}),kn=xn});var Y,Ie=f(()=>{"use strict";Fs();Ws();Bs();cn();Sn();On();Y={deno:As,npm:Es,pnpm:Us,ruby:on,uv:Pn,yarn:kn}});var Nn,Ln=f(()=>{"use strict";Ie();bt();Nn=async t=>{let e={};t.config.actions&&(e={...Object.entries(t.config.actions).reduce((s,[n,r])=>(s[n]=[r.command],s),{})});for(let[s,n]of Object.entries(Y)){let r=await n.actions(t);e=He(e,r)}return e}});var N,Uo,Bo,Uc,Yo,Rn,In=f(()=>{"use strict";N=require("zod");Ie();Uo=N.z.object({resolved:N.z.string().describe("The resolved version of the dependency"),specifier:N.z.string().describe("The version constraint/specifier used"),source:N.z.string().describe("The source file/path of the dependency"),wanted:N.z.string().describe("The wanted version based on semver rules").optional(),latest:N.z.string().describe("The latest available version of the dependency").optional()}),Bo=N.z.object({id:N.z.string().describe("Unique identifier for the ecosystem / dependency"),name:N.z.string().describe("Name of the dependency"),versions:N.z.array(Uo).describe("Map of resolved versions to sources. Each source maps a package path to its version specifier."),ecosystem:N.z.string().describe("Ecosystem of the dependency (e.g., npm, rubygems, pip)")}),Uc=Bo.extend({wanted:N.z.string().describe("Latest version compatible with the specifier (semver)"),latest:N.z.string().describe("Absolute latest version available"),specifier:N.z.string().describe("The version specifier from package manifest"),isDevDependency:N.z.boolean().describe("Whether this is a dev dependency")}),Yo=t=>{let e=new Map;for(let s of t){let n=e.get(s.id);n?e.set(s.id,{...n,versions:[...n.versions,...s.versions]}):e.set(s.id,s)}return Array.from(e.values())},Rn=async t=>{let s=(await Promise.all(Object.values(Y).map(n=>n.dependencies?n.dependencies(t):Promise.resolve([])))).flat();return Yo(s)}});function Ko(t){return(0,Tn.createHash)("sha1").update(t).digest("hex")}function fe(t){return t.slice(0,8)}var Tn,kt,k,se=f(()=>{"use strict";Tn=require("crypto"),kt=I(require("fs"),1);Ln();ce();In();ze();Ie();k=class{_path;_slug;_id;config;_rootFilesCache=null;constructor(e){this._path=e,this._slug=qe(e),this._id=Ko(e),this.config=Is(e)}get slug(){return this._slug}get id(){return this._id}get name(){return this.config.name??this._path.split("/").pop()??"unknown"}get path(){return this._path}get packageManagers(){let e=this.rootFiles,s=[];return e.includes("pnpm-lock.yaml")?s.push("pnpm"):e.includes("package-lock.json")?s.push("npm"):e.includes("yarn.lock")&&s.push("yarn"),(e.includes("deno.json")||e.includes("deno.jsonc"))&&s.push("deno"),e.includes("pyproject.toml")&&s.push("uv"),s}get primaryPackageManager(){return this.packageManagers[0]||null}async dependencies(){return await Rn(this)}async outdatedDependencies(e){return(await Promise.all(Object.values(Y).map(n=>n.outdatedDependencies?n.outdatedDependencies(this,e):Promise.resolve([])))).flat()}get actions(){return Nn(this)}get services(){return this.config.services||{}}get rootFiles(){return this._rootFilesCache===null&&(this._rootFilesCache=kt.default.readdirSync(this.path)),this._rootFilesCache}findFilesByName(e){let s=[],n=r=>{let o=kt.default.readdirSync(r,{withFileTypes:!0});for(let a of o)a.isDirectory()?a.name!=="node_modules"&&n(`${r}/${a.name}`):a.name===e&&s.push(`${r}/${a.name}`)};return n(this.path),s}}});var he,Zo,T,ne=f(()=>{"use strict";he=I(require("fs"),1);ce();ze();Zo=t=>{let s=oe(t).split("/"),n=[""];for(let r of s){if(r===""){n=n.map(o=>`${o}/`);continue}if(r==="*"){let o=[];for(let a of n){let i=a||"/";if(he.default.existsSync(i))try{let l=he.default.readdirSync(i,{withFileTypes:!0});for(let c of l)c.isDirectory()&&(c.name.startsWith(".")||o.push(`${a}${c.name}`))}catch{}}n=o}else n=n.map(o=>`${o}${r}`);n=n.map(o=>`${o}/`)}return n.map(r=>r.replace(/\/$/,"")).filter(r=>{try{return he.default.existsSync(r)&&he.default.statSync(r).isDirectory()}catch{return!1}})},T=t=>{let s=ie().projectPaths,n=t?.withConfig??!1,r=new Set,o=[];for(let a of s){let i=Zo(a);for(let l of i){if(r.has(l))continue;if(r.add(l),n){let p=`${l}/.denvig.yml`;if(!he.default.existsSync(p))continue}let c=qe(l);o.push({slug:c,path:l})}}return o.sort((a,i)=>a.slug.localeCompare(i.slug))}});var Ze,Ot,An,Nt=f(()=>{"use strict";se();ne();Ze=t=>{if(t.startsWith("id:")){let r=t.slice(3),o=r.indexOf("/");if(o===-1)return{type:"id",value:r};let a=r.slice(0,o),i=r.slice(o+1);return{type:"id",value:a,serviceName:i}}if(t.startsWith("github:")){let r=t.slice(7),o=r.split("/");if(o.length<=2)return{type:"github",value:r};let a=`${o[0]}/${o[1]}`,i=o.slice(2).join("/");return{type:"github",value:a,serviceName:i}}if(t.startsWith("local:"))return{type:"local",value:t.slice(6)};if(t.startsWith("/"))return{type:"path",value:t};if(t.startsWith("~"))return{type:"path",value:t};let e=t.split("/");if(e.length<=2)return{type:"github",value:t};let s=`${e[0]}/${e[1]}`,n=e.slice(2).join("/");return{type:"github",value:s,serviceName:n}},Ot=(t,e)=>{let s=T();switch(t.type){case"id":{for(let n of s){let r=new k(n.path);if(r.id===t.value||r.id.startsWith(t.value))return n.path}return null}case"github":{let n=s.find(r=>r.slug===`github:${t.value}`);return n?n.path:null}case"local":{let n=e(t.value),r=s.find(o=>o.path===n);return r?r.path:n}case"path":return e(t.value)}},An=(t,e)=>{let s=Ze(t);return{path:Ot(s,e),serviceName:s.serviceName}}});var b,C=f(()=>{"use strict";b=class{name;description;usage;example;args;flags;handler;completions;constructor(e){this.name=e.name,this.description=e.description||"",this.usage=e.usage,this.example=e.example,this.args=e.args,this.flags=e.flags,this.handler=e.handler,this.completions=e.completions}async run(e,s,n,r){try{return await this.handler({project:e,args:s,flags:n,extraArgs:r})}catch(o){return console.error(`Error executing command "${this.name}":`,o),{success:!1,message:"fail"}}}}});var Lt={};x(Lt,{runCommand:()=>Qo});var Fn,Qo,Rt=f(()=>{"use strict";Fn=require("child_process");C();ke();Qo=new b({name:"run",description:"Run an action from the project. If no action is specified, lists available actions.",usage:"run [action]",example:"run build",args:[{name:"action",description:"The action to run (e.g. build, test, deploy)",required:!1,type:"string"}],flags:[],completions:async({project:t})=>{let e=await t.actions;return Object.keys(e)},handler:async({project:t,args:e,flags:s,extraArgs:n=[]})=>{let r=await t.actions;if(!e.action){if(s.json)return console.log(JSON.stringify({actions:r})),{success:!0,message:"Actions listed."};console.log(`Denvig v${z()}`),console.log(""),console.log("Usage: denvig run [action] [...actionArgs]"),console.log(""),console.log("Available actions:");for(let i in r){if(!r[i])continue;let l=r[i];for(let c of l){let p=c.split(`
9
- `),d=p[0],u=p.slice(1);console.log(` ${i}: ${d}`);for(let m of u)m.trim()&&console.log(`${" ".repeat(i.length+4)}${m}`)}}return{success:!0,message:"No action specified."}}let o=r[e.action];if(!o)return console.error(`Action "${e.action}" not found in project ${t.name}.`),{success:!1,message:`Action "${e.action}" not found.`};let a={success:!0};for(let i of o){let l=`${i} ${n.join(" ")}`.trim();console.log(`$ ${l}`);let c={...process.env,DENVIG_PROJECT:t.slug},p=process.stdout.isTTY&&process.stdin.isTTY,d,u;p?process.platform==="darwin"?(d="script",u=["-q","/dev/null","sh","-c",l]):(d="script",u=["-q","-c",l,"/dev/null"]):(d="sh",u=["-c",l]);let m=(0,Fn.spawn)(d,u,{cwd:t.path,env:c,stdio:"inherit"}),v=await new Promise(g=>{m.on("close",y=>{g({success:y===0})})});v.success||(a=v)}return a}})});var K,Qe=f(()=>{"use strict";K=t=>t.replace(process.env.HOME||"/root","~")});var It={};x(It,{configCommand:()=>Xo});var En,_n,Xo,Tt=f(()=>{"use strict";En=require("yaml");C();ce();Qe();_n=t=>{let e=Object.fromEntries(Object.entries({...t,$sources:void 0}).filter(([s,n])=>n!==void 0));(0,En.stringify)(e,{indent:2,lineWidth:80}).trim().split(`
10
- `).map(s=>console.log(` ${K(s)}`))},Xo=new b({name:"config",description:"Display the current global and project configuration.",usage:"config",example:"config",args:[],flags:[],handler:({project:t,flags:e})=>{let s=ie(),n=t.config;if(e.json){let{$sources:r,...o}=s,{$sources:a,...i}=n;return console.log(JSON.stringify({global:{sources:r,config:o},project:{slug:t.slug,sources:a,config:i}})),{success:!0,message:"Configuration displayed."}}return console.log("Denvig Config"),console.log(""),console.log(`Global: ${s.$sources.map(r=>K(r)).join(", ")||"default"}`),_n(s),console.log(""),console.log(`Project: ${t.config.$sources.map(r=>K(r)).join(", ")||"default"}`),console.log(` slug: ${t.slug}`),_n(n),{success:!0,message:"Configuration displayed."}}})});var At={};x(At,{pluginsCommand:()=>ei});var ei,Ft=f(()=>{"use strict";C();Ie();ei=new b({name:"plugins",description:"Show a list of available plugins and their actions",usage:"plugins",example:"denvig plugins",args:[],flags:[],handler:async({project:t,flags:e})=>{let s={};for(let[n,r]of Object.entries(Y)){let o=await r.actions(t);s[n]={name:r.name,actions:o}}if(e.json)return console.log(JSON.stringify(s)),{success:!0};for(let[n,r]of Object.entries(s)){let o=Object.keys(r.actions);console.log(`${r.name}: ${o.length} actions`);for(let a of o)console.log(` - ${a}: ${r.actions[a].join(" && ")}`)}return{success:!0}}})});var _t={};x(_t,{versionCommand:()=>ti});var ti,Et=f(()=>{"use strict";C();ke();ti=new b({name:"version",description:"Show the current version of Denvig",usage:"version",example:"denvig version",args:[],flags:[],handler:({flags:t})=>{let e=z();return t.json?console.log(JSON.stringify({version:e})):console.log(`v${e}`),{success:!0}}})});function Xe(){return`gui/${process.getuid?.()??501}`}async function si(t){try{let e=Xe(),{stdout:s,stderr:n}=await ve(`launchctl bootstrap ${e} "${t}"`);return{success:!0,output:s||n}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ni(t){try{let e=Xe(),{stdout:s,stderr:n}=await ve(`launchctl bootout ${e}/${t}`);return{success:!0,output:s||n}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ri(t){try{let{stdout:e,stderr:s}=await ve(`launchctl start ${t}`);return{success:!0,output:e||s}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function oi(t){try{let{stdout:e,stderr:s}=await ve(`launchctl stop ${t}`);return{success:!0,output:e||s}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ii(t){try{let e=Xe(),{stdout:s}=await ve(`launchctl print ${e}/${t}`),n=s.match(/pid\s*=\s*(\d+)/),r=s.match(/state\s*=\s*(\w+)/),o=s.match(/last exit code\s*=\s*(\d+)/);return{label:t,pid:n?parseInt(n[1],10):void 0,state:r?r[1]:"unknown",status:r?r[1]:"unknown",lastExitCode:o?parseInt(o[1],10):void 0}}catch{return null}}async function ci(t){try{let{stdout:e}=await ve("launchctl list"),n=e.trim().split(`
11
- `).slice(1).map(r=>{let o=r.trim().split(/\s+/);return o.length<3?null:{pid:o[0]==="-"?"-":parseInt(o[0],10),status:parseInt(o[1],10),label:o[2]}}).filter(r=>r!==null);return t?n.filter(r=>r.label.includes(t)):n}catch{return[]}}var Wn,Mn,ve,O,ye=f(()=>{"use strict";Wn=require("child_process"),Mn=require("util"),ve=(0,Mn.promisify)(Wn.exec);O={bootstrap:si,bootout:ni,start:ri,stop:oi,print:ii,list:ci,getUserDomain:Xe}});function ai(t){let e={},s=t.split(`
12
- `);for(let n=0;n<s.length;n++){let r=s[n].trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o===-1)continue;let a=r.slice(0,o).trim(),i=r.slice(o+1).trim(),l=i.startsWith('"'),c=i.startsWith("'");if(l||c){let p=l?'"':"'",d=i.indexOf(p,1);if(d!==-1)i=i.slice(1,d);else{let u=i.indexOf("#");u!==-1&&(i=i.slice(0,u).trim())}}else{let p=i.indexOf("#");p!==-1&&(i=i.slice(0,p).trim())}a&&(e[a]=i)}return e}async function li(t){try{let e=await(0,et.readFile)(t,"utf-8");return ai(e)}catch(e){let s=e;throw s.code==="ENOENT"?new Error(`Environment file not found: ${t}`):new Error(`Failed to read environment file: ${s.message||"Unknown error"}`)}}async function Vn(t,e){let s={},n=e?.skipMissing??!1;for(let r of t){if(n)try{await(0,et.access)(r)}catch{continue}let o=await li(r);Object.assign(s,o)}return s}var et,Wt,Jn=f(()=>{"use strict";et=require("fs/promises"),Wt=[".env.development",".env.local"]});function be(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function pi(t){return`{ ${t.trim()}; } 2>&1 | while IFS= read -r line; do printf '[%s] %s\\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$line"; done`}function Gn(t){let{label:e,command:s,workingDirectory:n,environmentVariables:r={},standardOutPath:o,keepAlive:a,runAtLoad:i}=t,l=pi(s),c=Object.entries(r).map(([p,d])=>` <key>${be(p)}</key>
13
- <string>${be(d)}</string>`).join(`
8
+ `);if(r.length<3)continue;let o=r[0].split(",").map(p=>p.trim().replace(/"|:/g,"")),a=r[1]?.match(/version "(.+)"/)?.[1],i=r[2]?.match(/resolved "(.+)"/)?.[1];if(!a||!i)continue;let l={},c=!1;for(let p=3;p<r.length;p++){let d=r[p];if(d.trim()==="dependencies:"){c=!0;continue}if(c&&d.startsWith(" ")){let u=d.trim().match(/^"?([^"\s]+)"?\s+"?([^"]+)"?$/);u&&(l[u[1]]=u[2])}else c&&!d.startsWith(" ")&&(c=!1)}for(let p of o)p&&(s[p]={version:a,resolved:i,dependencies:Object.keys(l).length>0?l:void 0})}return{type:"success",object:s}},wn=t=>{let e={},s=zo(t),n=new Map;for(let[r,o]of Object.entries(s.object)){let a=/^(@?.+)@(.+)$/,[,i,l]=r.match(a)||[];i&&(n.has(i)||n.set(i,[]),n.get(i)?.push({version:o.version,specifier:l,deps:o.dependencies}))}for(let[r,o]of n.entries()){e[r]||(e[r]={versions:{}});for(let a of o)e[r].versions[a.version]||(e[r].versions[a.version]={}),e[r].versions[a.version]["yarn.lock"]=a.specifier;e[r].versions=Object.fromEntries(Object.entries(e[r].versions).sort((a,i)=>a[0].localeCompare(i[0],void 0,{numeric:!0})))}for(let[r,o]of n.entries())for(let a of o){if(!a.deps)continue;let i=`${r}@${a.version}`;for(let[l,c]of Object.entries(a.deps)){e[l]||(e[l]={versions:{}});let p=n.get(l);if(!p)continue;let u=p.find(m=>m.specifier===c)?.version||p[0]?.version;if(u){e[l].versions[u]||(e[l].versions[u]={});let m=`yarn.lock:${i}`;e[l].versions[u][m]=c}}}return{dependencies:e}}});function Uo(t){return t.includes("__metadata:")}function Ho(t){let e=t.match(/^(.+)@npm:/);if(e)return e[1];let s=t.lastIndexOf("@");return s>0?t.slice(0,s):t}var te,xn,$n,kn,On,Nn=f(()=>{"use strict";te=require("fs"),xn=require("yaml");St();Le();Cn();ee();$n=new Map;kn=_({name:"yarn",actions:async t=>{let e=t.rootFiles.includes("package.json"),s=t.rootFiles.includes("yarn.lock");if(!(e&&s))return{};let o=H(t)?.scripts||{};return{...Object.entries(o).map(([i,l])=>[i,`yarn run ${i}`]).reduce((i,[l,c])=>(i[l]=[c],i),{}),install:["yarn install"],outdated:["yarn outdated"]}},dependencies:async t=>{let e=`${t.path}/yarn.lock`,s=`${t.path}/package.json`;if(!(0,te.existsSync)(e)||!(0,te.existsSync)(s))return[];let n=$n.get(t.path);if(n)return n;let r=new Map,o=new Set,a=(g,y,j,P,D,$)=>{let V=r.get(g);V?V.versions.push({resolved:P,specifier:$,source:D}):r.set(g,{id:g,name:y,ecosystem:j,versions:[{resolved:P,specifier:$,source:D}]})};r.set("npm:yarn",{id:"npm:yarn",name:"yarn",ecosystem:"system",versions:[]});let i=(0,te.readFileSync)(e,"utf-8"),l=Uo(i),c=new Map,p=new Map,d=null;if(l){let g=(0,xn.parse)(i);for(let[y,j]of Object.entries(g)){if(y==="__metadata"||!j?.version||typeof j.version!="string")continue;let P=Ho(y),D=j;c.has(P)||c.set(P,new Map);let $=y.match(/@npm:(.+)$/);$&&c.get(P)?.set($[1],j.version),D.dependencies&&p.set(`${P}@${D.version}`,D.dependencies)}}else{d=wn(i);for(let[g,y]of Object.entries(d.dependencies)){c.has(g)||c.set(g,new Map);for(let[j,P]of Object.entries(y.versions)){let D=P["yarn.lock"];D&&c.get(g)?.set(D,j)}}}let u=[s],m=t.findFilesByName("package.json");u.push(...m);for(let g of u)try{let y=(0,te.readFileSync)(g,"utf-8"),j=JSON.parse(y),P=".";g!==s&&(P=g.replace(`${t.path}/`,"").replace("/package.json",""));let D=($,V)=>{if($)for(let[q,U]of Object.entries($)){o.add(q);let xe=c.get(q),ke=U;if(xe){let _e=xe.get(U);if(_e)ke=_e;else{let Ee=xe.values().next().value;Ee&&(ke=Ee)}}a(`npm:${q}`,q,"npm",ke,`${P}#${V}`,U)}};D(j.dependencies,"dependencies"),D(j.devDependencies,"devDependencies")}catch{}if(l){for(let[g,y]of p.entries())for(let[j,P]of Object.entries(y))if(!o.has(j)){let D=c.get(j),$=P;if(D){let q=D.get(P);if(q)$=q;else{let U=D.values().next().value;U&&($=U)}}let V=`yarn.lock:${g}`;a(`npm:${j}`,j,"npm",$,V,P)}}else if(d){for(let[g,y]of Object.entries(d.dependencies))if(!o.has(g))for(let[j,P]of Object.entries(y.versions))for(let[D,$]of Object.entries(P))D.startsWith("yarn.lock:")&&a(`npm:${g}`,g,"npm",j,D,$)}let v=Array.from(r.values()).sort((g,y)=>g.name.localeCompare(y.name));return $n.set(t.path,v),v},outdatedDependencies:async(t,e)=>{if(!(0,te.existsSync)(`${t.path}/yarn.lock`))return[];let s=await kn.dependencies?.(t);return s?Ye(s,e):[]}}),On=kn});var Y,Te=f(()=>{"use strict";_s();Ms();Ys();an();Dn();Nn();Y={deno:Fs,npm:Ws,pnpm:Bs,ruby:cn,uv:Sn,yarn:On}});var Ln,Rn=f(()=>{"use strict";Te();jt();Ln=async t=>{let e={};t.config.actions&&(e={...Object.entries(t.config.actions).reduce((s,[n,r])=>(s[n]=[r.command],s),{})});for(let[s,n]of Object.entries(Y)){let r=await n.actions(t);e=He(e,r)}return e}});var N,Bo,Yo,Bc,Ko,In,Tn=f(()=>{"use strict";N=require("zod");Te();Bo=N.z.object({resolved:N.z.string().describe("The resolved version of the dependency"),specifier:N.z.string().describe("The version constraint/specifier used"),source:N.z.string().describe("The source file/path of the dependency"),wanted:N.z.string().describe("The wanted version based on semver rules").optional(),latest:N.z.string().describe("The latest available version of the dependency").optional()}),Yo=N.z.object({id:N.z.string().describe("Unique identifier for the ecosystem / dependency"),name:N.z.string().describe("Name of the dependency"),versions:N.z.array(Bo).describe("Map of resolved versions to sources. Each source maps a package path to its version specifier."),ecosystem:N.z.string().describe("Ecosystem of the dependency (e.g., npm, rubygems, pip)")}),Bc=Yo.extend({wanted:N.z.string().describe("Latest version compatible with the specifier (semver)"),latest:N.z.string().describe("Absolute latest version available"),specifier:N.z.string().describe("The version specifier from package manifest"),isDevDependency:N.z.boolean().describe("Whether this is a dev dependency")}),Ko=t=>{let e=new Map;for(let s of t){let n=e.get(s.id);n?e.set(s.id,{...n,versions:[...n.versions,...s.versions]}):e.set(s.id,s)}return Array.from(e.values())},In=async t=>{let s=(await Promise.all(Object.values(Y).map(n=>n.dependencies?n.dependencies(t):Promise.resolve([])))).flat();return Ko(s)}});function Zo(t){return(0,An.createHash)("sha1").update(t).digest("hex")}function he(t){return t.slice(0,8)}var An,Ot,k,se=f(()=>{"use strict";An=require("crypto"),Ot=I(require("fs"),1);Rn();ae();Tn();Ue();Te();k=class{_path;_slug;_id;config;_rootFilesCache=null;constructor(e){this._path=e,this._slug=ze(e),this._id=Zo(e),this.config=Ts(e)}get slug(){return this._slug}get id(){return this._id}get name(){return this.config.name??this._path.split("/").pop()??"unknown"}get path(){return this._path}get packageManagers(){let e=this.rootFiles,s=[];return e.includes("pnpm-lock.yaml")?s.push("pnpm"):e.includes("package-lock.json")?s.push("npm"):e.includes("yarn.lock")&&s.push("yarn"),(e.includes("deno.json")||e.includes("deno.jsonc"))&&s.push("deno"),e.includes("pyproject.toml")&&s.push("uv"),s}get primaryPackageManager(){return this.packageManagers[0]||null}async dependencies(){return await In(this)}async outdatedDependencies(e){return(await Promise.all(Object.values(Y).map(n=>n.outdatedDependencies?n.outdatedDependencies(this,e):Promise.resolve([])))).flat()}get actions(){return Ln(this)}get services(){return this.config.services||{}}get rootFiles(){return this._rootFilesCache===null&&(this._rootFilesCache=Ot.default.readdirSync(this.path)),this._rootFilesCache}findFilesByName(e){let s=[],n=r=>{let o=Ot.default.readdirSync(r,{withFileTypes:!0});for(let a of o)a.isDirectory()?a.name!=="node_modules"&&n(`${r}/${a.name}`):a.name===e&&s.push(`${r}/${a.name}`)};return n(this.path),s}}});var ve,Qo,T,ne=f(()=>{"use strict";ve=I(require("fs"),1);ae();Ue();Qo=t=>{let s=ie(t).split("/"),n=[""];for(let r of s){if(r===""){n=n.map(o=>`${o}/`);continue}if(r==="*"){let o=[];for(let a of n){let i=a||"/";if(ve.default.existsSync(i))try{let l=ve.default.readdirSync(i,{withFileTypes:!0});for(let c of l)c.isDirectory()&&(c.name.startsWith(".")||o.push(`${a}${c.name}`))}catch{}}n=o}else n=n.map(o=>`${o}${r}`);n=n.map(o=>`${o}/`)}return n.map(r=>r.replace(/\/$/,"")).filter(r=>{try{return ve.default.existsSync(r)&&ve.default.statSync(r).isDirectory()}catch{return!1}})},T=t=>{let s=ce().projectPaths,n=t?.withConfig??!1,r=new Set,o=[];for(let a of s){let i=Qo(a);for(let l of i){if(r.has(l))continue;if(r.add(l),n){let p=`${l}/.denvig.yml`;if(!ve.default.existsSync(p))continue}let c=ze(l);o.push({slug:c,path:l})}}return o.sort((a,i)=>a.slug.localeCompare(i.slug))}});var Qe,Nt,Fn,Lt=f(()=>{"use strict";se();ne();Qe=t=>{if(t.startsWith("id:")){let r=t.slice(3),o=r.indexOf("/");if(o===-1)return{type:"id",value:r};let a=r.slice(0,o),i=r.slice(o+1);return{type:"id",value:a,serviceName:i}}if(t.startsWith("github:")){let r=t.slice(7),o=r.split("/");if(o.length<=2)return{type:"github",value:r};let a=`${o[0]}/${o[1]}`,i=o.slice(2).join("/");return{type:"github",value:a,serviceName:i}}if(t.startsWith("local:"))return{type:"local",value:t.slice(6)};if(t.startsWith("/"))return{type:"path",value:t};if(t.startsWith("~"))return{type:"path",value:t};let e=t.split("/");if(e.length<=2)return{type:"github",value:t};let s=`${e[0]}/${e[1]}`,n=e.slice(2).join("/");return{type:"github",value:s,serviceName:n}},Nt=(t,e)=>{let s=T();switch(t.type){case"id":{for(let n of s){let r=new k(n.path);if(r.id===t.value||r.id.startsWith(t.value))return n.path}return null}case"github":{let n=s.find(r=>r.slug===`github:${t.value}`);return n?n.path:null}case"local":{let n=e(t.value),r=s.find(o=>o.path===n);return r?r.path:n}case"path":return e(t.value)}},Fn=(t,e)=>{let s=Qe(t);return{path:Nt(s,e),serviceName:s.serviceName}}});var b,C=f(()=>{"use strict";b=class{name;description;usage;example;args;flags;handler;completions;constructor(e){this.name=e.name,this.description=e.description||"",this.usage=e.usage,this.example=e.example,this.args=e.args,this.flags=e.flags,this.handler=e.handler,this.completions=e.completions}async run(e,s,n,r){try{return await this.handler({project:e,args:s,flags:n,extraArgs:r})}catch(o){return console.error(`Error executing command "${this.name}":`,o),{success:!1,message:"fail"}}}}});var Rt={};x(Rt,{runCommand:()=>Xo});var _n,Xo,It=f(()=>{"use strict";_n=require("child_process");C();Oe();Xo=new b({name:"run",description:"Run an action from the project. If no action is specified, lists available actions.",usage:"run [action]",example:"run build",args:[{name:"action",description:"The action to run (e.g. build, test, deploy)",required:!1,type:"string"}],flags:[],completions:async({project:t})=>{let e=await t.actions;return Object.keys(e)},handler:async({project:t,args:e,flags:s,extraArgs:n=[]})=>{let r=await t.actions;if(!e.action){if(s.json)return console.log(JSON.stringify({actions:r})),{success:!0,message:"Actions listed."};console.log(`Denvig v${z()}`),console.log(""),console.log("Usage: denvig run [action] [...actionArgs]"),console.log(""),console.log("Available actions:");for(let i in r){if(!r[i])continue;let l=r[i];for(let c of l){let p=c.split(`
9
+ `),d=p[0],u=p.slice(1);console.log(` ${i}: ${d}`);for(let m of u)m.trim()&&console.log(`${" ".repeat(i.length+4)}${m}`)}}return{success:!0,message:"No action specified."}}let o=r[e.action];if(!o)return console.error(`Action "${e.action}" not found in project ${t.name}.`),{success:!1,message:`Action "${e.action}" not found.`};let a={success:!0};for(let i of o){let l=`${i} ${n.join(" ")}`.trim();console.log(`$ ${l}`);let c={...process.env,DENVIG_PROJECT:t.slug},p=process.stdout.isTTY&&process.stdin.isTTY,d,u;p?process.platform==="darwin"?(d="script",u=["-q","/dev/null","sh","-c",l]):(d="script",u=["-q","-c",l,"/dev/null"]):(d="sh",u=["-c",l]);let m=(0,_n.spawn)(d,u,{cwd:t.path,env:c,stdio:"inherit"}),v=await new Promise(g=>{m.on("close",y=>{g({success:y===0})})});v.success||(a=v)}return a}})});var K,Xe=f(()=>{"use strict";K=t=>t.replace(process.env.HOME||"/root","~")});var Tt={};x(Tt,{configCommand:()=>ei});var Wn,En,ei,At=f(()=>{"use strict";Wn=require("yaml");C();ae();Xe();En=t=>{let e=Object.fromEntries(Object.entries({...t,$sources:void 0}).filter(([s,n])=>n!==void 0));(0,Wn.stringify)(e,{indent:2,lineWidth:80}).trim().split(`
10
+ `).map(s=>console.log(` ${K(s)}`))},ei=new b({name:"config",description:"Display the current global and project configuration.",usage:"config",example:"config",args:[],flags:[],handler:({project:t,flags:e})=>{let s=ce(),n=t.config;if(e.json){let{$sources:r,...o}=s,{$sources:a,...i}=n;return console.log(JSON.stringify({global:{sources:r,config:o},project:{slug:t.slug,sources:a,config:i}})),{success:!0,message:"Configuration displayed."}}return console.log("Denvig Config"),console.log(""),console.log(`Global: ${s.$sources.map(r=>K(r)).join(", ")||"default"}`),En(s),console.log(""),console.log(`Project: ${t.config.$sources.map(r=>K(r)).join(", ")||"default"}`),console.log(` slug: ${t.slug}`),En(n),{success:!0,message:"Configuration displayed."}}})});var Ft={};x(Ft,{pluginsCommand:()=>ti});var ti,_t=f(()=>{"use strict";C();Te();ti=new b({name:"plugins",description:"Show a list of available plugins and their actions",usage:"plugins",example:"denvig plugins",args:[],flags:[],handler:async({project:t,flags:e})=>{let s={};for(let[n,r]of Object.entries(Y)){let o=await r.actions(t);s[n]={name:r.name,actions:o}}if(e.json)return console.log(JSON.stringify(s)),{success:!0};for(let[n,r]of Object.entries(s)){let o=Object.keys(r.actions);console.log(`${r.name}: ${o.length} actions`);for(let a of o)console.log(` - ${a}: ${r.actions[a].join(" && ")}`)}return{success:!0}}})});var Et={};x(Et,{versionCommand:()=>si});var si,Wt=f(()=>{"use strict";C();Oe();si=new b({name:"version",description:"Show the current version of Denvig",usage:"version",example:"denvig version",args:[],flags:[],handler:({flags:t})=>{let e=z();return t.json?console.log(JSON.stringify({version:e})):console.log(`v${e}`),{success:!0}}})});function et(){return`gui/${process.getuid?.()??501}`}async function ni(t){try{let e=et(),{stdout:s,stderr:n}=await ye(`launchctl bootstrap ${e} "${t}"`);return{success:!0,output:s||n}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ri(t){try{let e=et(),{stdout:s,stderr:n}=await ye(`launchctl bootout ${e}/${t}`);return{success:!0,output:s||n}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function oi(t){try{let{stdout:e,stderr:s}=await ye(`launchctl start ${t}`);return{success:!0,output:e||s}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ii(t){try{let{stdout:e,stderr:s}=await ye(`launchctl stop ${t}`);return{success:!0,output:e||s}}catch(e){let s=e;return{success:!1,output:s.stderr||s.message||"Unknown error"}}}async function ci(t){try{let e=et(),{stdout:s}=await ye(`launchctl print ${e}/${t}`),n=s.match(/pid\s*=\s*(\d+)/),r=s.match(/state\s*=\s*(\w+)/),o=s.match(/last exit code\s*=\s*(\d+)/);return{label:t,pid:n?parseInt(n[1],10):void 0,state:r?r[1]:"unknown",status:r?r[1]:"unknown",lastExitCode:o?parseInt(o[1],10):void 0}}catch{return null}}async function ai(t){try{let{stdout:e}=await ye("launchctl list"),n=e.trim().split(`
11
+ `).slice(1).map(r=>{let o=r.trim().split(/\s+/);return o.length<3?null:{pid:o[0]==="-"?"-":parseInt(o[0],10),status:parseInt(o[1],10),label:o[2]}}).filter(r=>r!==null);return t?n.filter(r=>r.label.includes(t)):n}catch{return[]}}var Mn,Vn,ye,O,be=f(()=>{"use strict";Mn=require("child_process"),Vn=require("util"),ye=(0,Vn.promisify)(Mn.exec);O={bootstrap:ni,bootout:ri,start:oi,stop:ii,print:ci,list:ai,getUserDomain:et}});function li(t){let e={},s=t.split(`
12
+ `);for(let n=0;n<s.length;n++){let r=s[n].trim();if(!r||r.startsWith("#"))continue;let o=r.indexOf("=");if(o===-1)continue;let a=r.slice(0,o).trim(),i=r.slice(o+1).trim(),l=i.startsWith('"'),c=i.startsWith("'");if(l||c){let p=l?'"':"'",d=i.indexOf(p,1);if(d!==-1)i=i.slice(1,d);else{let u=i.indexOf("#");u!==-1&&(i=i.slice(0,u).trim())}}else{let p=i.indexOf("#");p!==-1&&(i=i.slice(0,p).trim())}a&&(e[a]=i)}return e}async function pi(t){try{let e=await(0,tt.readFile)(t,"utf-8");return li(e)}catch(e){let s=e;throw s.code==="ENOENT"?new Error(`Environment file not found: ${t}`):new Error(`Failed to read environment file: ${s.message||"Unknown error"}`)}}async function Jn(t,e){let s={},n=e?.skipMissing??!1;for(let r of t){if(n)try{await(0,tt.access)(r)}catch{continue}let o=await pi(r);Object.assign(s,o)}return s}var tt,Mt,Gn=f(()=>{"use strict";tt=require("fs/promises"),Mt=[".env.development",".env.local"]});function je(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function ui(t){return`{ ${t.trim()}; } 2>&1 | while IFS= read -r line; do printf '[%s] %s\\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$line"; done`}function qn(t){let{label:e,command:s,workingDirectory:n,environmentVariables:r={},standardOutPath:o,keepAlive:a,runAtLoad:i}=t,l=ui(s),c=Object.entries(r).map(([p,d])=>` <key>${je(p)}</key>
13
+ <string>${je(d)}</string>`).join(`
14
14
  `);return`<?xml version="1.0" encoding="UTF-8"?>
15
15
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
16
16
  <plist version="1.0">
17
17
  <dict>
18
18
  <key>Label</key>
19
- <string>${be(e)}</string>
19
+ <string>${je(e)}</string>
20
20
 
21
21
  <key>ProgramArguments</key>
22
22
  <array>
23
23
  <string>/bin/zsh</string>
24
24
  <string>-l</string>
25
25
  <string>-c</string>
26
- <string>${be(l)}</string>
26
+ <string>${je(l)}</string>
27
27
  </array>
28
28
 
29
29
  <key>WorkingDirectory</key>
30
- <string>${be(n)}</string>
30
+ <string>${je(n)}</string>
31
31
 
32
32
  <key>EnvironmentVariables</key>
33
33
  <dict>
@@ -35,7 +35,7 @@ ${c}
35
35
  </dict>
36
36
 
37
37
  <key>StandardOutPath</key>
38
- <string>${be(o)}</string>
38
+ <string>${je(o)}</string>
39
39
 
40
40
  <key>KeepAlive</key>
41
41
  <${a?"true":"false"}/>
@@ -44,12 +44,12 @@ ${c}
44
44
  <${i?"true":"false"}/>
45
45
  </dict>
46
46
  </plist>
47
- `}var qn=f(()=>{"use strict"});var L,tt,A,F,je=f(()=>{"use strict";L=require("fs/promises"),tt=require("os"),A=require("path");Jn();ye();qn();F=class{project;constructor(e){this.project=e}async listServices(){let e=this.project.config.services||{};return Object.entries(e).map(([s,n])=>({name:s,cwd:n.cwd||".",command:n.command,http:n.http,startOnBoot:n.startOnBoot}))}async buildServiceEnvironment(e){let s=this.getServiceConfig(e);if(!s)return{success:!1,message:`Service "${e}" not found in configuration`};let n=this.resolveServiceCwd(s),r={DENVIG_PROJECT:this.project.slug,DENVIG_SERVICE:e},o=s.envFiles??Wt;if(o.length>0)try{let a=o.map(l=>(0,A.resolve)(n,l)),i=await Vn(a,{skipMissing:!0});Object.assign(r,i)}catch(a){return{success:!1,message:`Failed to load environment file: ${a instanceof Error?a.message:"Unknown error"}`}}return s.env&&Object.assign(r,s.env),s.http?.port!==void 0&&(r.PORT=s.http.port.toString()),{success:!0,env:r}}async startService(e){let s=await this.buildServiceEnvironment(e);if(!s.success)return{name:e,success:!1,message:s.message};let n=this.getServiceConfig(e);if(!n)return{name:e,success:!1,message:`Service "${e}" not found in configuration`};let r=this.getServiceLabel(e),o=await this.isServiceBootstrapped(e);await this.ensureDenvigDirectories();let a=this.getPlistPath(e),i=this.resolveServiceCwd(n),l=Gn({label:r,command:n.command,workingDirectory:i,environmentVariables:s.env,standardOutPath:this.getLogPath(e,"stdout"),keepAlive:n.keepAlive??!0,runAtLoad:n.startOnBoot??!1});if(await(0,L.writeFile)(a,l,"utf-8"),o){let c=await O.bootout(r);if(!c.success)return{name:e,success:!1,message:`Failed to bootout service: ${c.output}`};await new Promise(d=>setTimeout(d,1e3));let p=await O.bootstrap(a);if(!p.success)return{name:e,success:!1,message:`Failed to bootstrap service: ${p.output}`}}else{let c=await O.bootstrap(a);if(!c.success)return{name:e,success:!1,message:`Failed to bootstrap service: ${c.output}`}}try{let c=new Date().toISOString();await(0,L.appendFile)(this.getLogPath(e,"stdout"),`[${c}] Service Started
47
+ `}var zn=f(()=>{"use strict"});var L,st,A,F,Pe=f(()=>{"use strict";L=require("fs/promises"),st=require("os"),A=require("path");Gn();be();zn();F=class{project;constructor(e){this.project=e}async listServices(){let e=this.project.config.services||{};return Object.entries(e).map(([s,n])=>({name:s,cwd:n.cwd||".",command:n.command,http:n.http,startOnBoot:n.startOnBoot}))}async buildServiceEnvironment(e){let s=this.getServiceConfig(e);if(!s)return{success:!1,message:`Service "${e}" not found in configuration`};let n=this.resolveServiceCwd(s),r={DENVIG_PROJECT:this.project.slug,DENVIG_SERVICE:e},o=s.envFiles??Mt;if(o.length>0)try{let a=o.map(l=>(0,A.resolve)(n,l)),i=await Jn(a,{skipMissing:!0});Object.assign(r,i)}catch(a){return{success:!1,message:`Failed to load environment file: ${a instanceof Error?a.message:"Unknown error"}`}}return s.env&&Object.assign(r,s.env),s.http?.port!==void 0&&(r.PORT=s.http.port.toString()),{success:!0,env:r}}async startService(e){let s=await this.buildServiceEnvironment(e);if(!s.success)return{name:e,success:!1,message:s.message};let n=this.getServiceConfig(e);if(!n)return{name:e,success:!1,message:`Service "${e}" not found in configuration`};let r=this.getServiceLabel(e),o=await this.isServiceBootstrapped(e);await this.ensureDenvigDirectories();let a=this.getPlistPath(e),i=this.resolveServiceCwd(n),l=qn({label:r,command:n.command,workingDirectory:i,environmentVariables:s.env,standardOutPath:this.getLogPath(e,"stdout"),keepAlive:n.keepAlive??!0,runAtLoad:n.startOnBoot??!1});if(await(0,L.writeFile)(a,l,"utf-8"),o){let c=await O.bootout(r);if(!c.success)return{name:e,success:!1,message:`Failed to bootout service: ${c.output}`};await new Promise(d=>setTimeout(d,1e3));let p=await O.bootstrap(a);if(!p.success)return{name:e,success:!1,message:`Failed to bootstrap service: ${p.output}`}}else{let c=await O.bootstrap(a);if(!c.success)return{name:e,success:!1,message:`Failed to bootstrap service: ${c.output}`}}try{let c=new Date().toISOString();await(0,L.appendFile)(this.getLogPath(e,"stdout"),`[${c}] Service Started
48
48
  `,"utf-8")}catch{}return{name:e,success:!0,message:"Service started successfully"}}async stopService(e){let s=this.getServiceConfig(e);if(!s)return{name:e,success:!1,message:`Service "${e}" not found in configuration`};let n=this.getServiceLabel(e);if(!await this.isServiceBootstrapped(e))return{name:e,success:!1,message:`Service "${e}" is not running`};if(s.startOnBoot){let o=await O.stop(n);if(!o.success)return{name:e,success:!1,message:`Failed to stop service: ${o.output}`}}else{let o=await O.bootout(n);if(!o.success)return{name:e,success:!1,message:`Failed to stop service: ${o.output}`};try{await(0,L.unlink)(this.getPlistPath(e))}catch{}}try{let o=new Date().toISOString();await(0,L.appendFile)(this.getLogPath(e,"stdout"),`[${o}] Service Stopped
49
- `,"utf-8")}catch{}return{name:e,success:!0,message:"Service stopped successfully"}}async restartService(e){if(!this.getServiceConfig(e))return{name:e,success:!1,message:`Service "${e}" not found in configuration`};if(await this.isServiceBootstrapped(e)){let r=await this.stopService(e);if(!r.success)return r}return await this.startService(e)}async getServiceStatus(e){let s=this.getServiceConfig(e);if(!s)return null;let n=this.getServiceLabel(e),r=await O.print(n);if(!r)return{name:e,running:!1,command:s.command,cwd:this.resolveServiceCwd(s),logPath:this.getLogPath(e,"stdout")};let o=await this.getRecentLogs(e,20);return{name:e,running:r.state==="running",pid:r.pid,command:s.command,cwd:this.resolveServiceCwd(s),logs:o,logPath:this.getLogPath(e,"stdout"),lastExitCode:r.lastExitCode}}async startAll(){let e=this.project.config.services||{},s=Object.keys(e);return await Promise.all(s.map(n=>this.startService(n)))}async stopAll(){let e=this.project.config.services||{},s=Object.keys(e),r=(await Promise.all(s.map(async o=>({name:o,isBootstrapped:await this.isServiceBootstrapped(o)})))).filter(o=>o.isBootstrapped).map(o=>o.name);return await Promise.all(r.map(o=>this.stopService(o)))}async restartAll(){let e=this.project.config.services||{},s=Object.keys(e),r=(await Promise.all(s.map(async o=>({name:o,isBootstrapped:await this.isServiceBootstrapped(o)})))).filter(o=>o.isBootstrapped).map(o=>o.name);return await Promise.all(r.map(o=>this.restartService(o)))}async teardownAll(e){let s=[],n=`denvig.${this.project.id}.`,r=[],o=await O.list(n);for(let i of o){let l=await O.bootout(i.label),c=i.label.replace(n,"");l.success?(r.push(i.label),s.push({name:c,success:!0,message:"Service removed from launchctl"})):s.push({name:c,success:!1,message:`Failed to bootout: ${l.output}`})}let a=(0,A.resolve)((0,tt.homedir)(),"Library","LaunchAgents");if(await Promise.all(r.map(async i=>{try{await(0,L.unlink)((0,A.resolve)(a,`${i}.plist`))}catch{}})),e?.removeLogs&&r.length>0){let i=(0,A.resolve)(this.getDenvigHomeDir(),"logs"),l=r.map(c=>c.replace("denvig.",""));await Promise.all(l.flatMap(c=>[(0,L.unlink)((0,A.resolve)(i,`${c}.log`)).catch(()=>{}),(0,L.unlink)((0,A.resolve)(i,`${c}.error.log`)).catch(()=>{})]))}return s}async isServiceBootstrapped(e){let s=this.getServiceLabel(e);return await O.print(s)!==null}normalizeForLabel(e){return e.replace(/\//g,"__").replace(/:/g,"-").replace(/[^a-zA-Z0-9_.-]/g,"_")}getServiceLabel(e){let s=this.normalizeForLabel(e);return`denvig.${this.project.id}.${s}`}getDenvigHomeDir(){return(0,A.resolve)((0,tt.homedir)(),".denvig")}getPlistPath(e){let s=this.getServiceLabel(e);return(0,A.resolve)((0,tt.homedir)(),"Library","LaunchAgents",`${s}.plist`)}getLogPath(e,s){let n=this.normalizeForLabel(e),r=s==="stderr"?".error":"";return(0,A.resolve)(this.getDenvigHomeDir(),"logs",`${this.project.id}.${n}${r}.log`)}async ensureDenvigDirectories(){let e=this.getDenvigHomeDir();await(0,L.mkdir)((0,A.resolve)(e,"logs"),{recursive:!0})}async getRecentLogs(e,s){try{let n=this.getLogPath(e,"stdout");return(await(0,L.readFile)(n,"utf-8")).trim().split(`
50
- `).slice(-s)}catch{return[]}}resolveServiceCwd(e){return(0,A.resolve)(this.project.path,e.cwd||".")}getServiceConfig(e){return this.project.config.services?.[e]}getServiceUrl(e){let s=this.getServiceConfig(e);return s?s.http?.domain?`${s.http.secure?"https":"http"}://${s.http.domain}`:s.http?.port?`http://localhost:${s.http.port}`:null:null}async plistExists(e){try{return await(0,L.access)(this.getPlistPath(e)),!0}catch{return!1}}async getServiceResponse(e,s){let n=this.getServiceConfig(e);if(!n)return null;let r=this.getServiceLabel(e),o="stopped",a=null,i=null;if(s?.launchctlList){let c=s.launchctlList.find(p=>p.label===r);c&&(a=c.pid==="-"?null:c.pid,i=c.status,a!==null?o=i!==0?"error":"running":o=i!==0?"error":"stopped")}else if(await this.plistExists(e)){let p=await O.print(r);p&&(a=p.pid??null,i=p.lastExitCode??null,p.state==="running"&&(i!==null&&i!==0?o="error":o="running"))}let l={name:e,project:{id:this.project.id,slug:this.project.slug,name:this.project.name,path:this.project.path},status:o,pid:a,url:this.getServiceUrl(e),command:n.command,cwd:this.resolveServiceCwd(n),logPath:this.getLogPath(e,"stdout"),envFiles:(n.envFiles??Wt).map(c=>(0,A.resolve)(this.resolveServiceCwd(n),c)),lastExitCode:i};return s?.includeLogs&&(l.logs=await this.getRecentLogs(e,s.logLines??20)),l}}});var Te,Mt=f(()=>{"use strict";ye();je();Te=async(t,e)=>{let s=t.config.$sources.length>0,n=e?.includeServiceStatus??!0,{$sources:r,...o}=t.config,a="none";if(n){let i=t.config.services||{},l=Object.keys(i);if(l.length>0){let c=e?.launchctlList??await O.list("denvig."),p=new F(t),d=!1;for(let u of l)if((await p.getServiceResponse(u,{launchctlList:c}))?.status==="running"){d=!0;break}a=d?"running":"stopped"}}return{id:t.id,slug:t.slug,name:t.name,path:t.path,config:s?o:null,serviceStatus:a}}});var Vt={};x(Vt,{infoCommand:()=>mi});var ui,mi,Jt=f(()=>{"use strict";C();Qe();Mt();ui=t=>{switch(t){case"running":return"\u{1F7E2}";case"stopped":return"\u25EF";default:return""}},mi=new b({name:"info",description:"Show information about the current project",usage:"info",example:"denvig info",args:[],flags:[],handler:async({project:t,flags:e})=>{let s=await Te(t);if(e.json)return console.log(JSON.stringify(s)),{success:!0};let n=ui(s.serviceStatus),r=n?`${n} `:"";return console.log(`${r}${s.config?.name||s.slug}`),console.log(` Path: ${K(s.path)}`),console.log(` Slug: ${s.slug}`),console.log(` ID: ${s.id}`),{success:!0}}})});var w,Pe,zn,Z,Se=f(()=>{"use strict";w={reset:"\x1B[0m",white:"\x1B[37m",grey:"\x1B[90m",green:"\x1B[32m",yellow:"\x1B[33m",red:"\x1B[31m",bold:"\x1B[1m"},Pe=t=>t.replace(/\x1b\[[0-9;]*m/g,""),zn=t=>{if(t.depth===0)return"";let e="";for(let s=0;s<t.parentPath.length-1;s++)e+=t.parentPath[s]?" ":"\u2502 ";return t.hasChildren?e+=t.isLast?"\u2514\u2500\u252C ":"\u251C\u2500\u252C ":e+=t.isLast?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",e},Z=t=>{let{columns:e,data:s,tree:n}=t,r=e.filter(c=>c.visible!==!1);if(s.length===0||r.length===0)return[];let o=r.map((c,p)=>{let d=c.header.length,u=Math.max(...s.map(m=>{let v=c.accessor(m);if(n&&p===0){let g={depth:n.getDepth(m),isLast:n.getIsLast(m),hasChildren:n.getHasChildren(m),parentPath:n.getParentPath(m)};v=zn(g)+Pe(v)}return Pe(v).length}));return Math.max(d,u)}),a=[],i=r.map((c,p)=>c.header.padEnd(o[p]));a.push(i.join(" "));let l=o.reduce((c,p)=>c+p,0)+(r.length-1)*2;a.push("-".repeat(l));for(let c of s){let d=(n?n.getDepth(c):0)>0,u=r.map((m,v)=>{let g=m.accessor(c),y=o[v];if(n&&v===0){let D={depth:n.getDepth(c),isLast:n.getIsLast(c),hasChildren:n.getHasChildren(c),parentPath:n.getParentPath(c)},$=zn(D),V=d?`${w.grey}${Pe(g)}${w.reset}`:g;g=$+V}else if(d&&!m.format){let D=Pe(g);D.trim()&&(g=`${w.grey}${D}${w.reset}`)}let j=Pe(g).length,P=y-j;if(m.format){let $=Pe(g).padEnd(y);return m.format($,c)}return g+" ".repeat(Math.max(0,P))});a.push(u.join(" "))}return a}});var Gt={};x(Gt,{servicesCommand:()=>gi});var di,gi,qt=f(()=>{"use strict";C();Se();se();ne();ye();je();di=t=>{switch(t){case"running":return"\u{1F7E2}";case"error":return"\u{1F534}";default:return"\u25EF"}},gi=new b({name:"services",description:"List all services across all projects",usage:"services",example:"services",args:[],flags:[],completions:()=>[],handler:async({project:t,flags:e})=>{let s=t.slug,n=T();if(n.length===0)return e.json?console.log(JSON.stringify([])):console.log("No projects found with .denvig.yml configuration."),{success:!0,message:"No projects found."};let r=await O.list("denvig."),o=[];for(let l of n){let c=new k(l.path),p=new F(c),d=await p.listServices();for(let u of d){let m=await p.getServiceResponse(u.name,{launchctlList:r});m&&o.push(m)}}if(o.length===0)return e.json?console.log(JSON.stringify([])):console.log("No services configured across any project."),{success:!0,message:"No services configured."};let a=o.sort((l,c)=>{let p=l.project.slug===s,d=c.project.slug===s;if(p&&!d)return-1;if(!p&&d)return 1;let u=l.project.slug.localeCompare(c.project.slug);return u!==0?u:l.name.localeCompare(c.name)});if(e.json)return console.log(JSON.stringify(a)),{success:!0,message:"Services listed successfully."};let i=Z({columns:[{header:"",accessor:l=>di(l.status)},{header:"Project",accessor:l=>l.project.slug},{header:"Name",accessor:l=>l.name},{header:"URL",accessor:l=>l.url||"-"}],data:a});for(let l of i)console.log(l);return console.log(""),console.log(`${o.length} service${o.length===1?"":"s"} configured across ${n.length} project${n.length===1?"":"s"}`),{success:!0,message:"Services listed successfully."}}})});var fi,hi,vi,Q,G,De=f(()=>{"use strict";ce();se();Nt();ne();je();fi=(t,e)=>{if(!t.includes("/"))return{projectSlug:e,serviceName:t};let s=Ze(t);if(s.serviceName!==void 0)return s.type==="id"?{projectSlug:"",projectId:s.value,serviceName:s.serviceName}:{projectSlug:s.type==="local"?`local:${s.value}`:`github:${s.value}`,serviceName:s.serviceName};if(s.type==="path"||s.type==="local")return{projectSlug:s.type==="local"?`local:${s.value}`:s.value,serviceName:""};let n=t.split("/"),r=n.pop();return{projectSlug:n.join("/"),serviceName:r}},hi=t=>{let e=T({withConfig:!0}),s=e.find(r=>r.slug===t);if(s)return s.path;let n=e.find(r=>r.slug.replace(/^(github|local):/,"")===t);return n?n.path:null},vi=t=>{let e=T({withConfig:!0});for(let s of e){let n=new k(s.path);if(n.id===t||n.id.startsWith(t))return s.path}return null},Q=(t,e)=>{let s=Ze(t);if(s.serviceName!==void 0&&s.serviceName!==""){let l=Ot(s,oe);if(l){let c=new k(l),p=new F(c);return{project:c,manager:p,serviceName:s.serviceName}}}let{projectSlug:n,projectId:r,serviceName:o}=fi(t,e.slug),a;if(r)if(e.id===r||e.id.startsWith(r))a=e;else{let l=vi(r);if(l)a=new k(l);else throw new Error(`Project with ID "${r}" not found`)}else if(n===e.slug)a=e;else{let l=hi(n);l?a=new k(l):a=new k(n)}let i=new F(a);return{project:a,manager:i,serviceName:o}},G=t=>{let e=[];for(let n of Object.keys(t.services))e.push(n);let s=T({withConfig:!0});for(let n of s)if(n.slug!==t.slug)try{let r=new k(n.path),o=n.slug.replace(/^(github|local):/,"");for(let a of Object.keys(r.services))e.push(`${o}/${a}`),e.push(`id:${fe(r.id)}/${a}`)}catch{}return e}});var zt={};x(zt,{servicesStartCommand:()=>yi});var Hn,yi,Ht=f(()=>{"use strict";Hn=require("zod");C();De();yi=new b({name:"services:start",description:"Start a service",usage:"services start <name>",example:"services start api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Hn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Starting ${i}${o}...`);let l=await r.startService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to start ${i}${o}: ${l.message}`),{success:!1,message:l.message};await new Promise(p=>setTimeout(p,2e3));let c=await r.getServiceResponse(o,{includeLogs:!0});if(c?.status==="running"){if(s.json)console.log(JSON.stringify(c));else{let p=c.url?` \u2192 ${c.url}`:"";console.log(`\u2713 ${i}${o} started successfully${p}`)}return{success:!0,message:"Service started successfully."}}if(s.json)console.log(JSON.stringify(c));else if(console.error(`\u2717 ${i}${o} failed to start`),c?.logs&&c.logs.length>0){console.error(""),console.error("Recent logs:");for(let p of c.logs)console.error(` ${p}`)}return{success:!1,message:"Service failed to start."}}})});var Ut={};x(Ut,{servicesStopCommand:()=>bi});var Un,bi,Bt=f(()=>{"use strict";Un=require("zod");C();De();bi=new b({name:"services:stop",description:"Stop a service",usage:"services stop <name>",example:"services stop api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Un.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Stopping ${i}${o}...`);let l=await r.stopService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to stop ${i}${o}: ${l.message}`),{success:!1,message:l.message};let c=await r.getServiceResponse(o);return s.json?console.log(JSON.stringify(c)):console.log(`\u2713 ${i}${o} stopped successfully`),{success:!0,message:"Service stopped successfully."}}})});var Yt={};x(Yt,{servicesRestartCommand:()=>ji});var Bn,ji,Kt=f(()=>{"use strict";Bn=require("zod");C();De();ji=new b({name:"services:restart",description:"Restart a service",usage:"services restart <name>",example:"services restart api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Bn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Restarting ${i}${o}...`);let l=await r.restartService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to restart ${i}${o}: ${l.message}`),{success:!1,message:l.message};await new Promise(p=>setTimeout(p,2e3));let c=await r.getServiceResponse(o,{includeLogs:!0});if(c?.status==="running"){if(s.json)console.log(JSON.stringify(c));else{let p=c.url?` \u2192 ${c.url}`:"";console.log(`\u2713 ${i}${o} restarted successfully${p}`)}return{success:!0,message:"Service restarted successfully."}}if(s.json)console.log(JSON.stringify(c));else if(console.error(`\u2717 ${i}${o} failed to restart`),c?.logs&&c.logs.length>0){console.error(""),console.error("Recent logs:");for(let p of c.logs)console.error(` ${p}`)}return{success:!1,message:"Service failed to restart."}}})});var Zt={};x(Zt,{servicesStatusCommand:()=>Pi});var Yn,st,Kn,Pi,Qt=f(()=>{"use strict";Yn=require("fs"),st=require("os"),Kn=require("zod");C();De();Pi=new b({name:"services:status",description:"Show status of a specific service",usage:"services status <name>",example:"services status api or services status marcqualie/denvig/hello",args:[{name:"name",description:"Service name or project/service path (e.g., hello or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Kn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=await r.getServiceResponse(o,{includeLogs:!0});if(!i){let d=a.slug!==t.slug?` in project "${a.slug}"`:"";return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:`Service "${o}" not found in configuration${d}`})):console.error(`Service "${o}" not found in configuration${d}`),{success:!1,message:`Service "${o}" not found.`}}if(s.json)return console.log(JSON.stringify(i)),{success:!0,message:"Status retrieved successfully."};let l=a.slug!==t.slug?`${a.slug}/`:"",c=i.status==="running"?"Running":i.status==="error"?"Error":"Stopped";console.log(`Service: ${l}${i.name}`),console.log(`Status: ${c}`),i.status==="running"&&i.pid&&console.log(`PID: ${i.pid}`),console.log(`Command: ${i.command}`),console.log(`CWD: ${i.cwd.replace((0,st.homedir)(),"~")}`),console.log(`Logs: ${i.logPath.replace((0,st.homedir)(),"~")}`);let p=r.getPlistPath(o);if((0,Yn.existsSync)(p)&&console.log(`Plist: ${p.replace((0,st.homedir)(),"~")}`),i.lastExitCode!==null&&i.lastExitCode!==0&&i.status!=="running"&&console.log(`Last exit code: ${i.lastExitCode}`),i.logs&&i.logs.length>0){console.log(""),console.log("Recent logs (last 10 lines):");for(let d of i.logs.slice(-10))console.log(` ${d}`)}return{success:!0,message:"Status retrieved successfully."}}})});var Xt={};x(Xt,{logsCommand:()=>Si});var Zn,Qn,Si,es=f(()=>{"use strict";Zn=require("child_process"),Qn=require("fs/promises");C();De();je();Si=new b({name:"services:logs",description:"Show logs for a service",usage:"services logs <name> [-n <lines>] [--follow]",example:"services logs api -n 50 --follow",args:[{name:"name",description:"Name of the service",required:!0,type:"string"}],flags:[{name:"lines",description:"Number of lines to show (use -n)",required:!1,type:"number",defaultValue:10},{name:"follow",description:"Follow the log output",required:!1,type:"boolean",defaultValue:!1}],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=new F(t),r=e.name,o=s.lines??s.n??10,a=!!s.follow,i=n.getLogPath(r,"stdout");if(a){if(s.json)return console.log(JSON.stringify({success:!1,error:"JSON format is not supported with --follow"})),{success:!1,message:"JSON format not supported with follow"};let l=["-n",`${o}`,"-f",i];return(0,Zn.spawn)("tail",l,{stdio:"inherit"}),new Promise(()=>{})}try{let p=(await(0,Qn.readFile)(i,"utf-8")).trim().split(`
51
- `).filter(Boolean).slice(-o);if(s.json)return console.log(JSON.stringify({service:r,logPath:i,lines:p})),{success:!0};for(let d of p)console.log(d);return{success:!0}}catch(l){let c=l instanceof Error?l.message:String(l);return s.json?console.log(JSON.stringify({success:!1,service:r,error:c})):console.error(`Failed to read logs for ${r}:`,c),{success:!1,message:"failed to read logs"}}}})});async function Xn(t){let e=[],s=[],n=await O.list("denvig.");for(let o of n){let a=await O.bootout(o.label);a.success?(s.push(o.label),e.push({name:o.label,success:!0,message:"Service removed from launchctl"})):e.push({name:o.label,success:!1,message:`Failed to bootout: ${a.output}`})}let r=(0,Ae.resolve)((0,ts.homedir)(),"Library","LaunchAgents");try{let a=(await(0,we.readdir)(r)).filter(i=>i.startsWith("denvig.")&&i.endsWith(".plist"));await Promise.all(a.map(async i=>{try{await(0,we.unlink)((0,Ae.resolve)(r,i))}catch{}}))}catch{}if(t?.removeLogs){let o=(0,Ae.resolve)((0,ts.homedir)(),".denvig","logs");try{let a=await(0,we.readdir)(o);await Promise.all(a.map(async i=>{try{await(0,we.unlink)((0,Ae.resolve)(o,i))}catch{}}))}catch{}}return{success:!0,services:e,logsRemoved:t?.removeLogs??!1}}async function er(t,e){let n=await new F(t).teardownAll({removeLogs:e?.removeLogs});return{success:!0,project:t.slug,services:n,logsRemoved:e?.removeLogs??!1}}var we,ts,Ae,tr=f(()=>{"use strict";we=require("fs/promises"),ts=require("os"),Ae=require("path");ye();je()});var ss={};x(ss,{servicesTeardownCommand:()=>Di});var Di,ns=f(()=>{"use strict";C();tr();Di=new b({name:"services:teardown",description:"Stop all services and remove them from launchctl",usage:"services teardown [--global] [--remove-logs]",example:"services teardown",args:[],flags:[{name:"global",description:"Teardown all denvig services across all projects",required:!1,type:"boolean",defaultValue:!1},{name:"remove-logs",description:"Also remove log files",required:!1,type:"boolean",defaultValue:!1}],handler:async({project:t,flags:e})=>{let s=e["remove-logs"];if(e.global){e.json||console.log("Tearing down all denvig services globally...");let o=await Xn({removeLogs:s});if(e.json)console.log(JSON.stringify(o));else if(o.services.length===0)console.log("No services found to teardown.");else{for(let a of o.services)a.success?console.log(`\u2713 ${a.name} removed`):console.log(`\u2717 ${a.name}: ${a.message}`);console.log(""),console.log(`Teardown complete. ${o.services.filter(a=>a.success).length}/${o.services.length} services removed.`),s&&console.log("Log files have been removed.")}return{success:!0,message:"Global teardown complete"}}e.json||console.log(`Tearing down all services for ${t.slug}...`);let r=await er(t,{removeLogs:s});if(e.json)console.log(JSON.stringify(r));else if(r.services.length===0)console.log("No services found to teardown.");else{for(let o of r.services)o.success?console.log(`\u2713 ${o.name} removed`):console.log(`\u2717 ${o.name}: ${o.message}`);console.log(""),console.log(`Teardown complete. ${r.services.filter(o=>o.success).length}/${r.services.length} services removed.`),s&&console.log("Log files have been removed.")}return{success:!0,message:"Teardown complete"}}})});var sr,rs,nr,rr=f(()=>{"use strict";sr=require("crypto"),rs=t=>{let{project:e,workspace:s="root",resource:n}=t;if(!n.startsWith("action/")&&!n.startsWith("service/"))throw new Error(`Invalid resource format: ${n}. Must start with "action/" or "service/".`);return`@${e.slug}|${s}|${n}`},nr=t=>{let e=rs(t),s=(0,sr.createHash)("sha256").update(e).digest("hex");return{id:e,hash:s}}});var or={};x(or,{internalsResourceHashCommand:()=>wi,internalsResourceIdCommand:()=>Ci});var wi,Ci,ir=f(()=>{"use strict";C();rr();wi=new b({name:"internals:resource-hash",description:"Generate hash for a denvig resource",usage:"internals:resource-hash <resource>",example:"denvig internals:resource-hash service/hello",args:[{name:"resource",description:"Resource identifier (e.g., service/api, action/build, apps/web|action/dev, or full ID)",required:!0,type:"string"}],flags:[{name:"workspace",description:'Workspace path (defaults to "root")',required:!1,type:"string"}],handler:async({project:t,args:e,flags:s})=>{let n=e.resource,r=s.workspace,o=n;if(n.startsWith("@")){let i=n.match(/^@([^#]+)#([^|]+)\|(.+)$/);if(!i)return s.json?console.log(JSON.stringify({success:!1,error:"Invalid full ID format. Expected: @project#workspace|resource"})):console.error("Error: Invalid full ID format. Expected: @project#workspace|resource"),{success:!1,message:"Invalid ID format"};r=i[2],o=i[3]}else if(n.includes("|")){let i=n.split("|");r=i[0],o=i[1]}if(!o.startsWith("action/")&&!o.startsWith("service/"))return s.json?console.log(JSON.stringify({success:!1,error:'Resource must start with "action/" or "service/" (e.g., service/api, action/build)'})):console.error('Error: Resource must start with "action/" or "service/" (e.g., service/api, action/build)'),{success:!1,message:"Invalid resource format"};let a=nr({project:t,workspace:r,resource:o});return s.json?console.log(JSON.stringify(a)):console.log(`${a.id}
52
- ${a.hash}`),{success:!0,message:"Hash generated successfully"}}}),Ci=new b({name:"internals:resource-id",description:"Generate ID for a denvig resource",usage:"internals:resource-id <resource>",example:"denvig internals:id service/hello",args:[{name:"resource",description:"Resource identifier (e.g., service/api, action/build, apps/web|action/dev)",required:!0,type:"string"}],flags:[{name:"workspace",description:'Workspace path (defaults to "root")',required:!1,type:"string"}],handler:async({project:t,args:e,flags:s})=>{let n=e.resource,r=s.workspace,o=n;if(n.includes("|")){let i=n.split("|");r=i[0],o=i[1]}if(!o.startsWith("action/")&&!o.startsWith("service/"))return s.json?console.log(JSON.stringify({success:!1,error:'Resource must start with "action/" or "service/" (e.g., service/api, action/build)'})):console.error('Error: Resource must start with "action/" or "service/" (e.g., service/api, action/build)'),{success:!1,message:"Invalid resource format"};let a=rs({project:t,workspace:r,resource:o});return s.json?console.log(JSON.stringify({id:a})):console.log(a),{success:!0,message:"ID generated successfully"}}})});var cr,os,is,$i,cs,ar,lr,as=f(()=>{"use strict";cr=["pnpm-lock.yaml:","yarn.lock:","Gemfile.lock:","uv.lock:"],os=t=>{for(let e of cr)if(t.startsWith(e)){let n=t.slice(e.length).match(/^([^@]+)@([^(@]+)/);if(n)return{name:n[1],version:n[2]}}return null},is=t=>cr.some(e=>t.startsWith(e)),$i=t=>t.endsWith("#dependencies"),cs=t=>t.endsWith("#devDependencies"),ar=(t,e,s)=>{let n=new Map;for(let l of t)n.set(l.name,l);let r=[],o=new Set;for(let l of t)if(!(s&&l.ecosystem!==s)){for(let c of l.versions)if(!is(c.source)){let p=cs(c.source);if($i(c.source)||p){let u=`${l.name}@${c.resolved}`;o.has(u)||(o.add(u),r.push({dep:l,version:c.resolved,isDevDependency:p,children:[]}))}}}if(e>0){let l=new Map;for(let p of t)if(!(s&&p.ecosystem!==s))for(let d of p.versions){let u=os(d.source);if(u){let m=`${u.name}@${u.version}`,v=l.get(m)||[];v.some(g=>g.name===p.name)||(v.push(p),l.set(m,v))}}let c=(p,d,u)=>{if(d>=e)return;let m=`${p.dep.name}@${p.version}`;if(u.has(m))return;u.add(m);let v=l.get(m)||[];for(let g of v){let y=g.versions.find(j=>{let P=os(j.source);return P?.name===p.dep.name&&P?.version===p.version});if(y){let j={dep:g,version:y.resolved,isDevDependency:!1,children:[]};p.children.push(j),c(j,d+1,new Set(u))}}p.children.sort((g,y)=>g.dep.name.localeCompare(y.dep.name))};for(let p of r)c(p,0,new Set)}r.sort((l,c)=>{let p=l.dep.ecosystem.localeCompare(c.dep.ecosystem);return p!==0?p:l.dep.name.localeCompare(c.dep.name)});let a=[],i=(l,c,p,d)=>{a.push({name:l.dep.name,version:l.version,ecosystem:l.dep.ecosystem,isDevDependency:l.isDevDependency,depth:c,isLast:p,hasChildren:l.children.length>0,parentPath:[...d]});let u=[...d,p];l.children.forEach((m,v)=>{i(m,c+1,v===l.children.length-1,u)})};return r.forEach((l,c)=>{i(l,0,c===r.length-1,[])}),a},lr=(t,e,s,n)=>{if(!is(s))return{name:t,version:e,children:[]};let r=[{name:t,version:e}],o=s,a=50,i=0;for(;i<a;){let p=os(o);if(!p)break;r.unshift({name:p.name,version:p.version});let d=n.get(p.name);if(!d)break;let u=d.versions.find(m=>m.resolved===p.version);if(!u||!is(u.source))break;o=u.source,i++}if(r.length===0)return null;let l={name:r[0].name,version:r[0].version,children:[]},c=l;for(let p=1;p<r.length;p++){let d={name:r[p].name,version:r[p].version,children:[]};c.children.push(d),c=d}return l}});var ls={};x(ls,{depsListCommand:()=>xi});var xi,ps=f(()=>{"use strict";C();as();Se();xi=new b({name:"deps:list",description:"List all dependencies detected by plugins",usage:"deps list [--depth <n>] [--ecosystem <name>]",example:"denvig deps list --depth 1",args:[],flags:[{name:"depth",description:"Show subdependencies up to N levels deep (default: 0)",required:!1,type:"number",defaultValue:0},{name:"ecosystem",description:"Filter to a specific ecosystem (e.g., npm, rubygems, pypi)",required:!1,type:"string",defaultValue:void 0}],handler:async({project:t,flags:e})=>{let s=e.ecosystem,n=e.depth??0,r=await t.dependencies();if(r.length===0)return e.json?console.log(JSON.stringify([])):console.log("No dependencies detected in this project."),{success:!0,message:"No dependencies detected."};let o=ar(r,n,s);if(o.length===0){if(e.json)console.log(JSON.stringify([]));else{let m=s?`No dependencies found for ecosystem "${s}".`:"No direct dependencies detected in this project.";console.log(m)}return{success:!0,message:s?`No dependencies found for ecosystem "${s}".`:"No direct dependencies detected in this project."}}if(e.json)return console.log(JSON.stringify(r)),{success:!0,message:"Dependencies listed successfully."};let i=new Set(o.map(m=>m.ecosystem)).size>1&&!s,l=Z({columns:[{header:"Package",accessor:m=>m.name},{header:"",accessor:m=>m.depth===0&&m.isDevDependency?`${w.grey}(dev)${w.reset}`:" "},{header:"Current",accessor:m=>m.version},{header:"Ecosystem",accessor:m=>m.ecosystem,visible:i}],data:o,tree:{getDepth:m=>m.depth,getIsLast:m=>m.isLast,getHasChildren:m=>m.hasChildren,getParentPath:m=>m.parentPath}});for(let m of l)console.log(m);let c=o.filter(m=>m.depth===0),p=c.filter(m=>!m.isDevDependency).length,d=c.filter(m=>m.isDevDependency).length,u=r.length-c.length;return console.log(""),console.log(`${r.length} total (${p} dependencies, ${d} devDependencies, ${u} subdependencies)`),{success:!0,message:"Dependencies listed successfully."}}})});var pr,us,ur,mr=f(()=>{"use strict";pr=I(require("semver"),1),us=(t,e)=>{if(t===e)return null;try{let s=pr.default.diff(t,e);return s?s==="major"||s==="premajor"?"major":s==="minor"||s==="preminor"?"minor":s==="patch"||s==="prepatch"||s==="prerelease"?"patch":null:null}catch{return null}},ur=(t,e)=>t===null?!1:e==="patch"?t==="patch":e==="minor"?t==="patch"||t==="minor":!1});var ms={};x(ms,{depsOutdatedCommand:()=>ki});var dr,ki,ds=f(()=>{"use strict";C();Se();mr();dr=(t,e)=>{if(t===e)return w.white;let s=us(t,e);return s?s==="major"?w.red:s==="minor"?w.yellow:s==="patch"?w.green:w.white:w.white},ki=new b({name:"deps:outdated",description:"Show outdated dependencies",usage:"deps outdated [--no-cache] [--semver patch|minor] [--ecosystem <name>]",example:"denvig deps outdated --semver patch",args:[],flags:[{name:"no-cache",description:"Skip cache and fetch fresh data from registry",required:!1,type:"boolean",defaultValue:!1},{name:"semver",description:'Filter by semver level: "patch" for patch updates only, "minor" for minor and patch updates',required:!1,type:"string",defaultValue:void 0},{name:"ecosystem",description:"Filter to a specific ecosystem (e.g., npm, rubygems, pypi)",required:!1,type:"string",defaultValue:void 0}],handler:async({project:t,flags:e})=>{let s=!e["no-cache"],n=e.semver,r=e.ecosystem;if(n&&n!=="patch"&&n!=="minor")return console.error(`Invalid --semver value: "${n}". Must be "patch" or "minor".`),{success:!1,message:"Invalid --semver value."};let a=await t.outdatedDependencies({cache:s}),i=u=>u.versions[0]?.resolved||"";if(r&&(a=a.filter(u=>u.ecosystem===r)),n&&(a=a.filter(u=>{let m=us(i(u),u.latest);return ur(m,n)})),a.length===0){if(e.json)console.log(JSON.stringify([]));else{let m="All dependencies are up to date!";r&&n?m=`No ${n}-level updates available for ecosystem "${r}".`:r?m=`No outdated dependencies found for ecosystem "${r}".`:n&&(m=`No ${n}-level updates available.`),console.log(m)}let u="All dependencies are up to date!";return r&&n?u=`No ${n}-level updates available for ecosystem "${r}".`:r?u=`No outdated dependencies found for ecosystem "${r}".`:n&&(u=`No ${n}-level updates available.`),{success:!0,message:u}}let l=a.sort((u,m)=>{let v=u.ecosystem.localeCompare(m.ecosystem);return v!==0?v:u.name.localeCompare(m.name)});if(e.json)return console.log(JSON.stringify(l)),{success:!0,message:"Outdated dependencies listed."};let p=new Set(a.map(u=>u.ecosystem)).size>1&&!r,d=Z({columns:[{header:"Package",accessor:u=>u.name},{header:"",accessor:u=>u.isDevDependency?`${w.grey}(dev)${w.reset}`:" "},{header:"Current",accessor:u=>i(u)},{header:"Wanted",accessor:u=>u.wanted,format:(u,m)=>`${dr(i(m),m.wanted)}${u}${w.reset}`},{header:"Latest",accessor:u=>u.latest,format:(u,m)=>`${dr(i(m),m.latest)}${u}${w.reset}`},{header:"Ecosystem",accessor:u=>u.ecosystem,visible:p}],data:l});for(let u of d)console.log(u);return{success:!0,message:"Outdated dependencies listed."}}})});var nt,rt,gr=f(()=>{"use strict";Se();nt=(t,e="",s=!0,n=!0)=>{let r=[],o=t.children.length>0;if(n)r.push(`${t.name} ${w.grey}${t.version}${w.reset}`);else{let i=o?s?"\u2514\u2500\u252C ":"\u251C\u2500\u252C ":s?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ";r.push(`${e}${i}${t.name} ${w.grey}${t.version}${w.reset}`)}let a=n?"":e+(s?" ":"\u2502 ");for(let i=0;i<t.children.length;i++){let l=t.children[i],c=i===t.children.length-1;r.push(...nt(l,a,c,!1))}return r},rt=(t,e)=>{let s=t.find(n=>n.name===e.name&&n.version===e.version);if(s)for(let n of e.children)rt(s.children,n);else t.push(e)}});var gs={};x(gs,{depsWhyCommand:()=>Oi});var Oi,fs=f(()=>{"use strict";C();as();gr();Oi=new b({name:"deps:why",description:"Show why a dependency is installed",usage:"deps why <dependency>",example:"denvig deps why yaml",args:[{name:"dependency",description:"The dependency name to look up",required:!0,type:"string"}],flags:[],completions:async({project:t})=>(await t.dependencies()).map(s=>s.name),handler:async({project:t,args:e,flags:s})=>{let n=e.dependency,r=await t.dependencies(),o=r.find(c=>c.name===n);if(!o)return s.json?console.log(JSON.stringify({dependency:n,found:!1,dependencies:[],devDependencies:[]})):console.log(`Dependency "${n}" not found in this project.`),{success:!1,message:"Dependency not found."};let a=new Map;for(let c of r)a.set(c.name,c);let i=[],l=[];for(let c of o.versions){let p=lr(o.name,c.resolved,c.source,a);p&&(a.get(p.name)?.versions.some(m=>cs(m.source))?rt(l,p):rt(i,p))}if(s.json)return console.log(JSON.stringify({dependency:n,found:!0,project:{name:t.name,path:t.path},dependencies:i,devDependencies:l})),{success:!0,message:"Dependency chain shown."};if(console.log(`${t.name} ${t.path}`),console.log(""),i.length>0){console.log("dependencies:");for(let c=0;c<i.length;c++){let p=nt(i[c],"",c===i.length-1,!0);for(let d of p)console.log(d)}console.log("")}if(l.length>0){console.log("devDependencies:");for(let c=0;c<l.length;c++){let p=nt(l[c],"",c===l.length-1,!0);for(let d of p)console.log(d)}console.log("")}return i.length===0&&l.length===0&&console.log(`Could not determine dependency chain for "${n}".`),{success:!0,message:"Dependency chain shown."}}})});var hs={};x(hs,{configVerifyCommand:()=>Ni});var fr,hr,Ni,vs=f(()=>{"use strict";fr=require("path"),hr=require("yaml");C();gt();dt();Ni=new b({name:"config:verify",description:"Verify a .denvig.yml file against the config schema.",usage:"config verify [path]",example:"config verify .denvig.yml",args:[{name:"path",description:"Path to the config file (defaults to .denvig.yml)",required:!1,type:"string",defaultValue:".denvig.yml"}],flags:[],handler:({project:t,args:e,flags:s})=>{let n=(0,fr.resolve)(t.path,e.path?.toString()||".denvig.yml"),r=Oe(n);if(!r)return s.json?console.log(JSON.stringify({valid:!1,path:n,error:"Config file not found."})):console.error(`Config file not found: ${n}`),{success:!1,message:"Config file not found."};let o;try{o=(0,hr.parse)(r)}catch(i){let l=i instanceof Error?i.message:"Unknown error";return s.json?console.log(JSON.stringify({valid:!1,path:n,error:`Invalid YAML syntax: ${l}`})):(console.error(`Failed to parse YAML at ${n}:`),console.error(` ${l}`)),{success:!1,message:"Invalid YAML syntax."}}let a=Ge.safeParse(o);if(!a.success){if(s.json)console.log(JSON.stringify({valid:!1,path:n,errors:a.error.issues.map(i=>({path:i.path.length>0?i.path.join("."):"(root)",message:i.message}))}));else{console.error(`Config validation failed for ${n}:`);for(let i of a.error.issues){let l=i.path.length>0?i.path.join("."):"(root)";console.error(` - ${l}: ${i.message}`)}}return{success:!1,message:"Config validation failed."}}return s.json?console.log(JSON.stringify({valid:!0,path:n})):console.log(`Config is valid: ${n}`),{success:!0,message:"Config is valid."}}})});var ys={};x(ys,{projectsListCommand:()=>Ri});var Li,Ri,bs=f(()=>{"use strict";C();Se();Qe();se();Mt();ne();ye();Li=t=>{switch(t){case"running":return"\u{1F7E2}";case"stopped":return"\u25EF";default:return""}},Ri=new b({name:"projects",description:"List all projects on the system",usage:"projects [list] [--with-config]",example:"projects --json",args:[],flags:[{name:"with-config",description:"Only show projects with a .denvig.yml configuration file",required:!1,type:"boolean",defaultValue:!1}],handler:async({flags:t})=>{let e=t["with-config"],s=T({withConfig:e});if(s.length===0)return t.json?console.log(JSON.stringify([])):console.log("No projects found."),{success:!0,message:"No projects found."};if(t.json){let i=[];for(let c of s){let p=new k(c.path),d=await Te(p,{includeServiceStatus:!1}),{serviceStatus:u,...m}=d;i.push(m)}let l=i.sort((c,p)=>c.path.localeCompare(p.path));return console.log(JSON.stringify(l)),{success:!0,message:"Projects listed successfully."}}let n=await O.list("denvig."),r=[];for(let i of s){let l=new k(i.path),c=await Te(l,{launchctlList:n});r.push(c)}let o=r.sort((i,l)=>i.path.localeCompare(l.path)),a=Z({columns:[{header:"",accessor:i=>Li(i.serviceStatus)},{header:"ID",accessor:i=>fe(i.id)},{header:"Name",accessor:i=>i.config?.name||i.slug},{header:"Path",accessor:i=>K(i.path)}],data:o});for(let i of a)console.log(i);return console.log(""),console.log(`${r.length} project${r.length===1?"":"s"} found`),{success:!0,message:"Projects listed successfully."}}})});var br={};x(br,{zshCompletionsCommand:()=>Ii});var Ce,yr,js,vr,Ii,jr=f(()=>{"use strict";Ce=I(require("fs"),1),yr=I(require("os"),1),js=I(require("path"),1);C();vr=`#compdef denvig
49
+ `,"utf-8")}catch{}return{name:e,success:!0,message:"Service stopped successfully"}}async restartService(e){if(!this.getServiceConfig(e))return{name:e,success:!1,message:`Service "${e}" not found in configuration`};if(await this.isServiceBootstrapped(e)){let r=await this.stopService(e);if(!r.success)return r}return await this.startService(e)}async getServiceStatus(e){let s=this.getServiceConfig(e);if(!s)return null;let n=this.getServiceLabel(e),r=await O.print(n);if(!r)return{name:e,running:!1,command:s.command,cwd:this.resolveServiceCwd(s),logPath:this.getLogPath(e,"stdout")};let o=await this.getRecentLogs(e,20);return{name:e,running:r.state==="running",pid:r.pid,command:s.command,cwd:this.resolveServiceCwd(s),logs:o,logPath:this.getLogPath(e,"stdout"),lastExitCode:r.lastExitCode}}async startAll(){let e=this.project.config.services||{},s=Object.keys(e);return await Promise.all(s.map(n=>this.startService(n)))}async stopAll(){let e=this.project.config.services||{},s=Object.keys(e),r=(await Promise.all(s.map(async o=>({name:o,isBootstrapped:await this.isServiceBootstrapped(o)})))).filter(o=>o.isBootstrapped).map(o=>o.name);return await Promise.all(r.map(o=>this.stopService(o)))}async restartAll(){let e=this.project.config.services||{},s=Object.keys(e),r=(await Promise.all(s.map(async o=>({name:o,isBootstrapped:await this.isServiceBootstrapped(o)})))).filter(o=>o.isBootstrapped).map(o=>o.name);return await Promise.all(r.map(o=>this.restartService(o)))}async teardownAll(e){let s=[],n=`denvig.${this.project.id}.`,r=[],o=await O.list(n);for(let i of o){let l=await O.bootout(i.label),c=i.label.replace(n,"");l.success?(r.push(i.label),s.push({name:c,success:!0,message:"Service removed from launchctl"})):s.push({name:c,success:!1,message:`Failed to bootout: ${l.output}`})}let a=(0,A.resolve)((0,st.homedir)(),"Library","LaunchAgents");if(await Promise.all(r.map(async i=>{try{await(0,L.unlink)((0,A.resolve)(a,`${i}.plist`))}catch{}})),e?.removeLogs&&r.length>0){let i=(0,A.resolve)(this.getDenvigHomeDir(),"logs"),l=r.map(c=>c.replace("denvig.",""));await Promise.all(l.flatMap(c=>[(0,L.unlink)((0,A.resolve)(i,`${c}.log`)).catch(()=>{}),(0,L.unlink)((0,A.resolve)(i,`${c}.error.log`)).catch(()=>{})]))}return s}async isServiceBootstrapped(e){let s=this.getServiceLabel(e);return await O.print(s)!==null}normalizeForLabel(e){return e.replace(/\//g,"__").replace(/:/g,"-").replace(/[^a-zA-Z0-9_.-]/g,"_")}getServiceLabel(e){let s=this.normalizeForLabel(e);return`denvig.${this.project.id}.${s}`}getDenvigHomeDir(){return(0,A.resolve)((0,st.homedir)(),".denvig")}getPlistPath(e){let s=this.getServiceLabel(e);return(0,A.resolve)((0,st.homedir)(),"Library","LaunchAgents",`${s}.plist`)}getLogPath(e,s){let n=this.normalizeForLabel(e),r=s==="stderr"?".error":"";return(0,A.resolve)(this.getDenvigHomeDir(),"logs",`${this.project.id}.${n}${r}.log`)}async ensureDenvigDirectories(){let e=this.getDenvigHomeDir();await(0,L.mkdir)((0,A.resolve)(e,"logs"),{recursive:!0})}async getRecentLogs(e,s){try{let n=this.getLogPath(e,"stdout");return(await(0,L.readFile)(n,"utf-8")).trim().split(`
50
+ `).slice(-s)}catch{return[]}}resolveServiceCwd(e){return(0,A.resolve)(this.project.path,e.cwd||".")}getServiceConfig(e){return this.project.config.services?.[e]}getServiceUrl(e){let s=this.getServiceConfig(e);return s?s.http?.domain?`${s.http.secure?"https":"http"}://${s.http.domain}`:s.http?.port?`http://localhost:${s.http.port}`:null:null}async plistExists(e){try{return await(0,L.access)(this.getPlistPath(e)),!0}catch{return!1}}async getServiceResponse(e,s){let n=this.getServiceConfig(e);if(!n)return null;let r=this.getServiceLabel(e),o="stopped",a=null,i=null;if(s?.launchctlList){let c=s.launchctlList.find(p=>p.label===r);c&&(a=c.pid==="-"?null:c.pid,i=c.status,a!==null?o=i!==0?"error":"running":o=i!==0?"error":"stopped")}else if(await this.plistExists(e)){let p=await O.print(r);p&&(a=p.pid??null,i=p.lastExitCode??null,p.state==="running"&&(i!==null&&i!==0?o="error":o="running"))}let l={name:e,project:{id:this.project.id,slug:this.project.slug,name:this.project.name,path:this.project.path},status:o,pid:a,url:this.getServiceUrl(e),command:n.command,cwd:this.resolveServiceCwd(n),logPath:this.getLogPath(e,"stdout"),envFiles:(n.envFiles??Mt).map(c=>(0,A.resolve)(this.resolveServiceCwd(n),c)),lastExitCode:i};return s?.includeLogs&&(l.logs=await this.getRecentLogs(e,s.logLines??20)),l}}});var Ae,Vt=f(()=>{"use strict";be();Pe();Ae=async(t,e)=>{let s=t.config.$sources.length>0,n=e?.includeServiceStatus??!0,{$sources:r,...o}=t.config,a="none";if(n){let i=t.config.services||{},l=Object.keys(i);if(l.length>0){let c=e?.launchctlList??await O.list("denvig."),p=new F(t),d=!1;for(let u of l)if((await p.getServiceResponse(u,{launchctlList:c}))?.status==="running"){d=!0;break}a=d?"running":"stopped"}}return{id:t.id,slug:t.slug,name:t.name,path:t.path,config:s?o:null,serviceStatus:a}}});var Jt={};x(Jt,{infoCommand:()=>di});var mi,di,Gt=f(()=>{"use strict";C();Xe();Vt();mi=t=>{switch(t){case"running":return"\u{1F7E2}";case"stopped":return"\u25EF";default:return""}},di=new b({name:"info",description:"Show information about the current project",usage:"info",example:"denvig info",args:[],flags:[],handler:async({project:t,flags:e})=>{let s=await Ae(t);if(e.json)return console.log(JSON.stringify(s)),{success:!0};let n=mi(s.serviceStatus),r=n?`${n} `:"";return console.log(`${r}${s.config?.name||s.slug}`),console.log(` Path: ${K(s.path)}`),console.log(` Slug: ${s.slug}`),console.log(` ID: ${s.id}`),{success:!0}}})});var re,w,Se,Un,Z,De=f(()=>{"use strict";re=()=>process.env.NO_COLOR!==void 0?!1:process.env.FORCE_COLOR!==void 0?!0:process.stdout.isTTY===!0,w={get reset(){return re()?"\x1B[0m":""},get white(){return re()?"\x1B[37m":""},get grey(){return re()?"\x1B[90m":""},get green(){return re()?"\x1B[32m":""},get yellow(){return re()?"\x1B[33m":""},get red(){return re()?"\x1B[31m":""},get bold(){return re()?"\x1B[1m":""}},Se=t=>t.replace(/\x1b\[[0-9;]*m/g,""),Un=t=>{if(t.depth===0)return"";let e="";for(let s=0;s<t.parentPath.length-1;s++)e+=t.parentPath[s]?" ":"\u2502 ";return t.hasChildren?e+=t.isLast?"\u2514\u2500\u252C ":"\u251C\u2500\u252C ":e+=t.isLast?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",e},Z=t=>{let{columns:e,data:s,tree:n}=t,r=e.filter(c=>c.visible!==!1);if(s.length===0||r.length===0)return[];let o=r.map((c,p)=>{let d=c.header.length,u=Math.max(...s.map(m=>{let v=c.accessor(m);if(n&&p===0){let g={depth:n.getDepth(m),isLast:n.getIsLast(m),hasChildren:n.getHasChildren(m),parentPath:n.getParentPath(m)};v=Un(g)+Se(v)}return Se(v).length}));return Math.max(d,u)}),a=[],i=r.map((c,p)=>c.header.padEnd(o[p]));a.push(i.join(" "));let l=o.reduce((c,p)=>c+p,0)+(r.length-1)*2;a.push("-".repeat(l));for(let c of s){let d=(n?n.getDepth(c):0)>0,u=r.map((m,v)=>{let g=m.accessor(c),y=o[v];if(n&&v===0){let D={depth:n.getDepth(c),isLast:n.getIsLast(c),hasChildren:n.getHasChildren(c),parentPath:n.getParentPath(c)},$=Un(D),V=d?`${w.grey}${Se(g)}${w.reset}`:g;g=$+V}else if(d&&!m.format){let D=Se(g);D.trim()&&(g=`${w.grey}${D}${w.reset}`)}let j=Se(g).length,P=y-j;if(m.format){let $=Se(g).padEnd(y);return m.format($,c)}return g+" ".repeat(Math.max(0,P))});a.push(u.join(" "))}return a}});var qt={};x(qt,{servicesCommand:()=>fi});var gi,fi,zt=f(()=>{"use strict";C();De();se();ne();be();Pe();gi=t=>{switch(t){case"running":return"\u{1F7E2}";case"error":return"\u{1F534}";default:return"\u25EF"}},fi=new b({name:"services",description:"List all services across all projects",usage:"services",example:"services",args:[],flags:[],completions:()=>[],handler:async({project:t,flags:e})=>{let s=t.slug,n=T();if(n.length===0)return e.json?console.log(JSON.stringify([])):console.log("No projects found with .denvig.yml configuration."),{success:!0,message:"No projects found."};let r=await O.list("denvig."),o=[];for(let l of n){let c=new k(l.path),p=new F(c),d=await p.listServices();for(let u of d){let m=await p.getServiceResponse(u.name,{launchctlList:r});m&&o.push(m)}}if(o.length===0)return e.json?console.log(JSON.stringify([])):console.log("No services configured across any project."),{success:!0,message:"No services configured."};let a=o.sort((l,c)=>{let p=l.project.slug===s,d=c.project.slug===s;if(p&&!d)return-1;if(!p&&d)return 1;let u=l.project.slug.localeCompare(c.project.slug);return u!==0?u:l.name.localeCompare(c.name)});if(e.json)return console.log(JSON.stringify(a)),{success:!0,message:"Services listed successfully."};let i=Z({columns:[{header:"",accessor:l=>gi(l.status)},{header:"Project",accessor:l=>l.project.slug},{header:"Name",accessor:l=>l.name},{header:"URL",accessor:l=>l.url||"-"}],data:a});for(let l of i)console.log(l);return console.log(""),console.log(`${o.length} service${o.length===1?"":"s"} configured across ${n.length} project${n.length===1?"":"s"}`),{success:!0,message:"Services listed successfully."}}})});var hi,vi,yi,Q,G,we=f(()=>{"use strict";ae();se();Lt();ne();Pe();hi=(t,e)=>{if(!t.includes("/"))return{projectSlug:e,serviceName:t};let s=Qe(t);if(s.serviceName!==void 0)return s.type==="id"?{projectSlug:"",projectId:s.value,serviceName:s.serviceName}:{projectSlug:s.type==="local"?`local:${s.value}`:`github:${s.value}`,serviceName:s.serviceName};if(s.type==="path"||s.type==="local")return{projectSlug:s.type==="local"?`local:${s.value}`:s.value,serviceName:""};let n=t.split("/"),r=n.pop();return{projectSlug:n.join("/"),serviceName:r}},vi=t=>{let e=T({withConfig:!0}),s=e.find(r=>r.slug===t);if(s)return s.path;let n=e.find(r=>r.slug.replace(/^(github|local):/,"")===t);return n?n.path:null},yi=t=>{let e=T({withConfig:!0});for(let s of e){let n=new k(s.path);if(n.id===t||n.id.startsWith(t))return s.path}return null},Q=(t,e)=>{let s=Qe(t);if(s.serviceName!==void 0&&s.serviceName!==""){let l=Nt(s,ie);if(l){let c=new k(l),p=new F(c);return{project:c,manager:p,serviceName:s.serviceName}}}let{projectSlug:n,projectId:r,serviceName:o}=hi(t,e.slug),a;if(r)if(e.id===r||e.id.startsWith(r))a=e;else{let l=yi(r);if(l)a=new k(l);else throw new Error(`Project with ID "${r}" not found`)}else if(n===e.slug)a=e;else{let l=vi(n);l?a=new k(l):a=new k(n)}let i=new F(a);return{project:a,manager:i,serviceName:o}},G=t=>{let e=[];for(let n of Object.keys(t.services))e.push(n);let s=T({withConfig:!0});for(let n of s)try{let r=new k(n.path),o=n.slug.replace(/^(github|local):/,"");for(let a of Object.keys(r.services))e.push(`${o}/${a}`),e.push(`id:${he(r.id)}/${a}`)}catch{}return e}});var Ut={};x(Ut,{servicesStartCommand:()=>bi});var Hn,bi,Ht=f(()=>{"use strict";Hn=require("zod");C();we();bi=new b({name:"services:start",description:"Start a service",usage:"services start <name>",example:"services start api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Hn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Starting ${i}${o}...`);let l=await r.startService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to start ${i}${o}: ${l.message}`),{success:!1,message:l.message};await new Promise(p=>setTimeout(p,2e3));let c=await r.getServiceResponse(o,{includeLogs:!0});if(c?.status==="running"){if(s.json)console.log(JSON.stringify(c));else{let p=c.url?` \u2192 ${c.url}`:"";console.log(`\u2713 ${i}${o} started successfully${p}`)}return{success:!0,message:"Service started successfully."}}if(s.json)console.log(JSON.stringify(c));else if(console.error(`\u2717 ${i}${o} failed to start`),c?.logs&&c.logs.length>0){console.error(""),console.error("Recent logs:");for(let p of c.logs)console.error(` ${p}`)}return{success:!1,message:"Service failed to start."}}})});var Bt={};x(Bt,{servicesStopCommand:()=>ji});var Bn,ji,Yt=f(()=>{"use strict";Bn=require("zod");C();we();ji=new b({name:"services:stop",description:"Stop a service",usage:"services stop <name>",example:"services stop api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Bn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Stopping ${i}${o}...`);let l=await r.stopService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to stop ${i}${o}: ${l.message}`),{success:!1,message:l.message};let c=await r.getServiceResponse(o);return s.json?console.log(JSON.stringify(c)):console.log(`\u2713 ${i}${o} stopped successfully`),{success:!0,message:"Service stopped successfully."}}})});var Kt={};x(Kt,{servicesRestartCommand:()=>Pi});var Yn,Pi,Zt=f(()=>{"use strict";Yn=require("zod");C();we();Pi=new b({name:"services:restart",description:"Restart a service",usage:"services restart <name>",example:"services restart api",args:[{name:"name",description:"Service name or project/service path (e.g., api or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Yn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=a.slug!==t.slug?`${a.slug}/`:"";s.json||console.log(`Restarting ${i}${o}...`);let l=await r.restartService(o);if(!l.success)return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:l.message})):console.error(`\u2717 Failed to restart ${i}${o}: ${l.message}`),{success:!1,message:l.message};await new Promise(p=>setTimeout(p,2e3));let c=await r.getServiceResponse(o,{includeLogs:!0});if(c?.status==="running"){if(s.json)console.log(JSON.stringify(c));else{let p=c.url?` \u2192 ${c.url}`:"";console.log(`\u2713 ${i}${o} restarted successfully${p}`)}return{success:!0,message:"Service restarted successfully."}}if(s.json)console.log(JSON.stringify(c));else if(console.error(`\u2717 ${i}${o} failed to restart`),c?.logs&&c.logs.length>0){console.error(""),console.error("Recent logs:");for(let p of c.logs)console.error(` ${p}`)}return{success:!1,message:"Service failed to restart."}}})});var Qt={};x(Qt,{servicesStatusCommand:()=>Si});var Kn,nt,Zn,Si,Xt=f(()=>{"use strict";Kn=require("fs"),nt=require("os"),Zn=require("zod");C();we();Si=new b({name:"services:status",description:"Show status of a specific service",usage:"services status <name>",example:"services status api or services status marcqualie/denvig/hello",args:[{name:"name",description:"Service name or project/service path (e.g., hello or marcqualie/denvig/hello)",required:!0,type:"string"}],flags:[],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=Zn.z.string().parse(e.name),{manager:r,serviceName:o,project:a}=Q(n,t),i=await r.getServiceResponse(o,{includeLogs:!0});if(!i){let d=a.slug!==t.slug?` in project "${a.slug}"`:"";return s.json?console.log(JSON.stringify({success:!1,service:o,project:a.slug,message:`Service "${o}" not found in configuration${d}`})):console.error(`Service "${o}" not found in configuration${d}`),{success:!1,message:`Service "${o}" not found.`}}if(s.json)return console.log(JSON.stringify(i)),{success:!0,message:"Status retrieved successfully."};let l=a.slug!==t.slug?`${a.slug}/`:"",c=i.status==="running"?"Running":i.status==="error"?"Error":"Stopped";console.log(`Service: ${l}${i.name}`),console.log(`Status: ${c}`),i.status==="running"&&i.pid&&console.log(`PID: ${i.pid}`),console.log(`Command: ${i.command}`),console.log(`CWD: ${i.cwd.replace((0,nt.homedir)(),"~")}`),console.log(`Logs: ${i.logPath.replace((0,nt.homedir)(),"~")}`);let p=r.getPlistPath(o);if((0,Kn.existsSync)(p)&&console.log(`Plist: ${p.replace((0,nt.homedir)(),"~")}`),i.lastExitCode!==null&&i.lastExitCode!==0&&i.status!=="running"&&console.log(`Last exit code: ${i.lastExitCode}`),i.logs&&i.logs.length>0){console.log(""),console.log("Recent logs (last 10 lines):");for(let d of i.logs.slice(-10))console.log(` ${d}`)}return{success:!0,message:"Status retrieved successfully."}}})});var es={};x(es,{logsCommand:()=>Di});var Qn,Xn,Di,ts=f(()=>{"use strict";Qn=require("child_process"),Xn=require("fs/promises");C();we();Pe();Di=new b({name:"services:logs",description:"Show logs for a service",usage:"services logs <name> [-n <lines>] [--follow]",example:"services logs api -n 50 --follow",args:[{name:"name",description:"Name of the service",required:!0,type:"string"}],flags:[{name:"lines",description:"Number of lines to show (use -n)",required:!1,type:"number",defaultValue:10},{name:"follow",description:"Follow the log output",required:!1,type:"boolean",defaultValue:!1}],completions:({project:t})=>G(t),handler:async({project:t,args:e,flags:s})=>{let n=new F(t),r=e.name,o=s.lines??s.n??10,a=!!s.follow,i=n.getLogPath(r,"stdout");if(a){if(s.json)return console.log(JSON.stringify({success:!1,error:"JSON format is not supported with --follow"})),{success:!1,message:"JSON format not supported with follow"};let l=["-n",`${o}`,"-f",i];return(0,Qn.spawn)("tail",l,{stdio:"inherit"}),new Promise(()=>{})}try{let p=(await(0,Xn.readFile)(i,"utf-8")).trim().split(`
51
+ `).filter(Boolean).slice(-o);if(s.json)return console.log(JSON.stringify({service:r,logPath:i,lines:p})),{success:!0};for(let d of p)console.log(d);return{success:!0}}catch(l){let c=l instanceof Error?l.message:String(l);return s.json?console.log(JSON.stringify({success:!1,service:r,error:c})):console.error(`Failed to read logs for ${r}:`,c),{success:!1,message:"failed to read logs"}}}})});async function er(t){let e=[],s=[],n=await O.list("denvig.");for(let o of n){let a=await O.bootout(o.label);a.success?(s.push(o.label),e.push({name:o.label,success:!0,message:"Service removed from launchctl"})):e.push({name:o.label,success:!1,message:`Failed to bootout: ${a.output}`})}let r=(0,Fe.resolve)((0,ss.homedir)(),"Library","LaunchAgents");try{let a=(await(0,Ce.readdir)(r)).filter(i=>i.startsWith("denvig.")&&i.endsWith(".plist"));await Promise.all(a.map(async i=>{try{await(0,Ce.unlink)((0,Fe.resolve)(r,i))}catch{}}))}catch{}if(t?.removeLogs){let o=(0,Fe.resolve)((0,ss.homedir)(),".denvig","logs");try{let a=await(0,Ce.readdir)(o);await Promise.all(a.map(async i=>{try{await(0,Ce.unlink)((0,Fe.resolve)(o,i))}catch{}}))}catch{}}return{success:!0,services:e,logsRemoved:t?.removeLogs??!1}}async function tr(t,e){let n=await new F(t).teardownAll({removeLogs:e?.removeLogs});return{success:!0,project:t.slug,services:n,logsRemoved:e?.removeLogs??!1}}var Ce,ss,Fe,sr=f(()=>{"use strict";Ce=require("fs/promises"),ss=require("os"),Fe=require("path");be();Pe()});var ns={};x(ns,{servicesTeardownCommand:()=>wi});var wi,rs=f(()=>{"use strict";C();sr();wi=new b({name:"services:teardown",description:"Stop all services and remove them from launchctl",usage:"services teardown [--global] [--remove-logs]",example:"services teardown",args:[],flags:[{name:"global",description:"Teardown all denvig services across all projects",required:!1,type:"boolean",defaultValue:!1},{name:"remove-logs",description:"Also remove log files",required:!1,type:"boolean",defaultValue:!1}],handler:async({project:t,flags:e})=>{let s=e["remove-logs"];if(e.global){e.json||console.log("Tearing down all denvig services globally...");let o=await er({removeLogs:s});if(e.json)console.log(JSON.stringify(o));else if(o.services.length===0)console.log("No services found to teardown.");else{for(let a of o.services)a.success?console.log(`\u2713 ${a.name} removed`):console.log(`\u2717 ${a.name}: ${a.message}`);console.log(""),console.log(`Teardown complete. ${o.services.filter(a=>a.success).length}/${o.services.length} services removed.`),s&&console.log("Log files have been removed.")}return{success:!0,message:"Global teardown complete"}}e.json||console.log(`Tearing down all services for ${t.slug}...`);let r=await tr(t,{removeLogs:s});if(e.json)console.log(JSON.stringify(r));else if(r.services.length===0)console.log("No services found to teardown.");else{for(let o of r.services)o.success?console.log(`\u2713 ${o.name} removed`):console.log(`\u2717 ${o.name}: ${o.message}`);console.log(""),console.log(`Teardown complete. ${r.services.filter(o=>o.success).length}/${r.services.length} services removed.`),s&&console.log("Log files have been removed.")}return{success:!0,message:"Teardown complete"}}})});var nr,os,rr,or=f(()=>{"use strict";nr=require("crypto"),os=t=>{let{project:e,workspace:s="root",resource:n}=t;if(!n.startsWith("action/")&&!n.startsWith("service/"))throw new Error(`Invalid resource format: ${n}. Must start with "action/" or "service/".`);return`@${e.slug}|${s}|${n}`},rr=t=>{let e=os(t),s=(0,nr.createHash)("sha256").update(e).digest("hex");return{id:e,hash:s}}});var ir={};x(ir,{internalsResourceHashCommand:()=>Ci,internalsResourceIdCommand:()=>$i});var Ci,$i,cr=f(()=>{"use strict";C();or();Ci=new b({name:"internals:resource-hash",description:"Generate hash for a denvig resource",usage:"internals:resource-hash <resource>",example:"denvig internals:resource-hash service/hello",args:[{name:"resource",description:"Resource identifier (e.g., service/api, action/build, apps/web|action/dev, or full ID)",required:!0,type:"string"}],flags:[{name:"workspace",description:'Workspace path (defaults to "root")',required:!1,type:"string"}],handler:async({project:t,args:e,flags:s})=>{let n=e.resource,r=s.workspace,o=n;if(n.startsWith("@")){let i=n.match(/^@([^#]+)#([^|]+)\|(.+)$/);if(!i)return s.json?console.log(JSON.stringify({success:!1,error:"Invalid full ID format. Expected: @project#workspace|resource"})):console.error("Error: Invalid full ID format. Expected: @project#workspace|resource"),{success:!1,message:"Invalid ID format"};r=i[2],o=i[3]}else if(n.includes("|")){let i=n.split("|");r=i[0],o=i[1]}if(!o.startsWith("action/")&&!o.startsWith("service/"))return s.json?console.log(JSON.stringify({success:!1,error:'Resource must start with "action/" or "service/" (e.g., service/api, action/build)'})):console.error('Error: Resource must start with "action/" or "service/" (e.g., service/api, action/build)'),{success:!1,message:"Invalid resource format"};let a=rr({project:t,workspace:r,resource:o});return s.json?console.log(JSON.stringify(a)):console.log(`${a.id}
52
+ ${a.hash}`),{success:!0,message:"Hash generated successfully"}}}),$i=new b({name:"internals:resource-id",description:"Generate ID for a denvig resource",usage:"internals:resource-id <resource>",example:"denvig internals:id service/hello",args:[{name:"resource",description:"Resource identifier (e.g., service/api, action/build, apps/web|action/dev)",required:!0,type:"string"}],flags:[{name:"workspace",description:'Workspace path (defaults to "root")',required:!1,type:"string"}],handler:async({project:t,args:e,flags:s})=>{let n=e.resource,r=s.workspace,o=n;if(n.includes("|")){let i=n.split("|");r=i[0],o=i[1]}if(!o.startsWith("action/")&&!o.startsWith("service/"))return s.json?console.log(JSON.stringify({success:!1,error:'Resource must start with "action/" or "service/" (e.g., service/api, action/build)'})):console.error('Error: Resource must start with "action/" or "service/" (e.g., service/api, action/build)'),{success:!1,message:"Invalid resource format"};let a=os({project:t,workspace:r,resource:o});return s.json?console.log(JSON.stringify({id:a})):console.log(a),{success:!0,message:"ID generated successfully"}}})});var ar,is,cs,xi,as,lr,pr,ls=f(()=>{"use strict";ar=["pnpm-lock.yaml:","yarn.lock:","Gemfile.lock:","uv.lock:"],is=t=>{for(let e of ar)if(t.startsWith(e)){let n=t.slice(e.length).match(/^([^@]+)@([^(@]+)/);if(n)return{name:n[1],version:n[2]}}return null},cs=t=>ar.some(e=>t.startsWith(e)),xi=t=>t.endsWith("#dependencies"),as=t=>t.endsWith("#devDependencies"),lr=(t,e,s)=>{let n=new Map;for(let l of t)n.set(l.name,l);let r=[],o=new Set;for(let l of t)if(!(s&&l.ecosystem!==s)){for(let c of l.versions)if(!cs(c.source)){let p=as(c.source);if(xi(c.source)||p){let u=`${l.name}@${c.resolved}`;o.has(u)||(o.add(u),r.push({dep:l,version:c.resolved,isDevDependency:p,children:[]}))}}}if(e>0){let l=new Map;for(let p of t)if(!(s&&p.ecosystem!==s))for(let d of p.versions){let u=is(d.source);if(u){let m=`${u.name}@${u.version}`,v=l.get(m)||[];v.some(g=>g.name===p.name)||(v.push(p),l.set(m,v))}}let c=(p,d,u)=>{if(d>=e)return;let m=`${p.dep.name}@${p.version}`;if(u.has(m))return;u.add(m);let v=l.get(m)||[];for(let g of v){let y=g.versions.find(j=>{let P=is(j.source);return P?.name===p.dep.name&&P?.version===p.version});if(y){let j={dep:g,version:y.resolved,isDevDependency:!1,children:[]};p.children.push(j),c(j,d+1,new Set(u))}}p.children.sort((g,y)=>g.dep.name.localeCompare(y.dep.name))};for(let p of r)c(p,0,new Set)}r.sort((l,c)=>{let p=l.dep.ecosystem.localeCompare(c.dep.ecosystem);return p!==0?p:l.dep.name.localeCompare(c.dep.name)});let a=[],i=(l,c,p,d)=>{a.push({name:l.dep.name,version:l.version,ecosystem:l.dep.ecosystem,isDevDependency:l.isDevDependency,depth:c,isLast:p,hasChildren:l.children.length>0,parentPath:[...d]});let u=[...d,p];l.children.forEach((m,v)=>{i(m,c+1,v===l.children.length-1,u)})};return r.forEach((l,c)=>{i(l,0,c===r.length-1,[])}),a},pr=(t,e,s,n)=>{if(!cs(s))return{name:t,version:e,children:[]};let r=[{name:t,version:e}],o=s,a=50,i=0;for(;i<a;){let p=is(o);if(!p)break;r.unshift({name:p.name,version:p.version});let d=n.get(p.name);if(!d)break;let u=d.versions.find(m=>m.resolved===p.version);if(!u||!cs(u.source))break;o=u.source,i++}if(r.length===0)return null;let l={name:r[0].name,version:r[0].version,children:[]},c=l;for(let p=1;p<r.length;p++){let d={name:r[p].name,version:r[p].version,children:[]};c.children.push(d),c=d}return l}});var ps={};x(ps,{depsListCommand:()=>ki});var ki,us=f(()=>{"use strict";C();ls();De();ki=new b({name:"deps:list",description:"List all dependencies detected by plugins",usage:"deps list [--depth <n>] [--ecosystem <name>]",example:"denvig deps list --depth 1",args:[],flags:[{name:"depth",description:"Show subdependencies up to N levels deep (default: 0)",required:!1,type:"number",defaultValue:0},{name:"ecosystem",description:"Filter to a specific ecosystem (e.g., npm, rubygems, pypi)",required:!1,type:"string",defaultValue:void 0}],handler:async({project:t,flags:e})=>{let s=e.ecosystem,n=e.depth??0,r=await t.dependencies();if(r.length===0)return e.json?console.log(JSON.stringify([])):console.log("No dependencies detected in this project."),{success:!0,message:"No dependencies detected."};let o=lr(r,n,s);if(o.length===0){if(e.json)console.log(JSON.stringify([]));else{let m=s?`No dependencies found for ecosystem "${s}".`:"No direct dependencies detected in this project.";console.log(m)}return{success:!0,message:s?`No dependencies found for ecosystem "${s}".`:"No direct dependencies detected in this project."}}if(e.json)return console.log(JSON.stringify(r)),{success:!0,message:"Dependencies listed successfully."};let i=new Set(o.map(m=>m.ecosystem)).size>1&&!s,l=Z({columns:[{header:"Package",accessor:m=>m.name},{header:"",accessor:m=>m.depth===0&&m.isDevDependency?`${w.grey}(dev)${w.reset}`:" "},{header:"Current",accessor:m=>m.version},{header:"Ecosystem",accessor:m=>m.ecosystem,visible:i}],data:o,tree:{getDepth:m=>m.depth,getIsLast:m=>m.isLast,getHasChildren:m=>m.hasChildren,getParentPath:m=>m.parentPath}});for(let m of l)console.log(m);let c=o.filter(m=>m.depth===0),p=c.filter(m=>!m.isDevDependency).length,d=c.filter(m=>m.isDevDependency).length,u=r.length-c.length;return console.log(""),console.log(`${r.length} total (${p} dependencies, ${d} devDependencies, ${u} subdependencies)`),{success:!0,message:"Dependencies listed successfully."}}})});var ur,ms,mr,dr=f(()=>{"use strict";ur=I(require("semver"),1),ms=(t,e)=>{if(t===e)return null;try{let s=ur.default.diff(t,e);return s?s==="major"||s==="premajor"?"major":s==="minor"||s==="preminor"?"minor":s==="patch"||s==="prepatch"||s==="prerelease"?"patch":null:null}catch{return null}},mr=(t,e)=>t===null?!1:e==="patch"?t==="patch":e==="minor"?t==="patch"||t==="minor":!1});var ds={};x(ds,{depsOutdatedCommand:()=>Oi});var gr,Oi,gs=f(()=>{"use strict";C();De();dr();gr=(t,e)=>{if(t===e)return w.white;let s=ms(t,e);return s?s==="major"?w.red:s==="minor"?w.yellow:s==="patch"?w.green:w.white:w.white},Oi=new b({name:"deps:outdated",description:"Show outdated dependencies",usage:"deps outdated [--no-cache] [--semver patch|minor] [--ecosystem <name>]",example:"denvig deps outdated --semver patch",args:[],flags:[{name:"no-cache",description:"Skip cache and fetch fresh data from registry",required:!1,type:"boolean",defaultValue:!1},{name:"semver",description:'Filter by semver level: "patch" for patch updates only, "minor" for minor and patch updates',required:!1,type:"string",defaultValue:void 0},{name:"ecosystem",description:"Filter to a specific ecosystem (e.g., npm, rubygems, pypi)",required:!1,type:"string",defaultValue:void 0}],handler:async({project:t,flags:e})=>{let s=!e["no-cache"],n=e.semver,r=e.ecosystem;if(n&&n!=="patch"&&n!=="minor")return console.error(`Invalid --semver value: "${n}". Must be "patch" or "minor".`),{success:!1,message:"Invalid --semver value."};let a=await t.outdatedDependencies({cache:s}),i=u=>u.versions[0]?.resolved||"";if(r&&(a=a.filter(u=>u.ecosystem===r)),n&&(a=a.filter(u=>{let m=ms(i(u),u.latest);return mr(m,n)})),a.length===0){if(e.json)console.log(JSON.stringify([]));else{let m="All dependencies are up to date!";r&&n?m=`No ${n}-level updates available for ecosystem "${r}".`:r?m=`No outdated dependencies found for ecosystem "${r}".`:n&&(m=`No ${n}-level updates available.`),console.log(m)}let u="All dependencies are up to date!";return r&&n?u=`No ${n}-level updates available for ecosystem "${r}".`:r?u=`No outdated dependencies found for ecosystem "${r}".`:n&&(u=`No ${n}-level updates available.`),{success:!0,message:u}}let l=a.sort((u,m)=>{let v=u.ecosystem.localeCompare(m.ecosystem);return v!==0?v:u.name.localeCompare(m.name)});if(e.json)return console.log(JSON.stringify(l)),{success:!0,message:"Outdated dependencies listed."};let p=new Set(a.map(u=>u.ecosystem)).size>1&&!r,d=Z({columns:[{header:"Package",accessor:u=>u.name},{header:"",accessor:u=>u.isDevDependency?`${w.grey}(dev)${w.reset}`:" "},{header:"Current",accessor:u=>i(u)},{header:"Wanted",accessor:u=>u.wanted,format:(u,m)=>`${gr(i(m),m.wanted)}${u}${w.reset}`},{header:"Latest",accessor:u=>u.latest,format:(u,m)=>`${gr(i(m),m.latest)}${u}${w.reset}`},{header:"Ecosystem",accessor:u=>u.ecosystem,visible:p}],data:l});for(let u of d)console.log(u);return{success:!0,message:"Outdated dependencies listed."}}})});var rt,ot,fr=f(()=>{"use strict";De();rt=(t,e="",s=!0,n=!0)=>{let r=[],o=t.children.length>0;if(n)r.push(`${t.name} ${w.grey}${t.version}${w.reset}`);else{let i=o?s?"\u2514\u2500\u252C ":"\u251C\u2500\u252C ":s?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ";r.push(`${e}${i}${t.name} ${w.grey}${t.version}${w.reset}`)}let a=n?"":e+(s?" ":"\u2502 ");for(let i=0;i<t.children.length;i++){let l=t.children[i],c=i===t.children.length-1;r.push(...rt(l,a,c,!1))}return r},ot=(t,e)=>{let s=t.find(n=>n.name===e.name&&n.version===e.version);if(s)for(let n of e.children)ot(s.children,n);else t.push(e)}});var fs={};x(fs,{depsWhyCommand:()=>Ni});var Ni,hs=f(()=>{"use strict";C();ls();fr();Ni=new b({name:"deps:why",description:"Show why a dependency is installed",usage:"deps why <dependency>",example:"denvig deps why yaml",args:[{name:"dependency",description:"The dependency name to look up",required:!0,type:"string"}],flags:[],completions:async({project:t})=>(await t.dependencies()).map(s=>s.name),handler:async({project:t,args:e,flags:s})=>{let n=e.dependency,r=await t.dependencies(),o=r.find(c=>c.name===n);if(!o)return s.json?console.log(JSON.stringify({dependency:n,found:!1,dependencies:[],devDependencies:[]})):console.log(`Dependency "${n}" not found in this project.`),{success:!1,message:"Dependency not found."};let a=new Map;for(let c of r)a.set(c.name,c);let i=[],l=[];for(let c of o.versions){let p=pr(o.name,c.resolved,c.source,a);p&&(a.get(p.name)?.versions.some(m=>as(m.source))?ot(l,p):ot(i,p))}if(s.json)return console.log(JSON.stringify({dependency:n,found:!0,project:{name:t.name,path:t.path},dependencies:i,devDependencies:l})),{success:!0,message:"Dependency chain shown."};if(console.log(`${t.name} ${t.path}`),console.log(""),i.length>0){console.log("dependencies:");for(let c=0;c<i.length;c++){let p=rt(i[c],"",c===i.length-1,!0);for(let d of p)console.log(d)}console.log("")}if(l.length>0){console.log("devDependencies:");for(let c=0;c<l.length;c++){let p=rt(l[c],"",c===l.length-1,!0);for(let d of p)console.log(d)}console.log("")}return i.length===0&&l.length===0&&console.log(`Could not determine dependency chain for "${n}".`),{success:!0,message:"Dependency chain shown."}}})});var vs={};x(vs,{configVerifyCommand:()=>Li});var hr,vr,Li,ys=f(()=>{"use strict";hr=require("path"),vr=require("yaml");C();ft();gt();Li=new b({name:"config:verify",description:"Verify a .denvig.yml file against the config schema.",usage:"config verify [path]",example:"config verify .denvig.yml",args:[{name:"path",description:"Path to the config file (defaults to .denvig.yml)",required:!1,type:"string",defaultValue:".denvig.yml"}],flags:[],handler:({project:t,args:e,flags:s})=>{let n=(0,hr.resolve)(t.path,e.path?.toString()||".denvig.yml"),r=Ne(n);if(!r)return s.json?console.log(JSON.stringify({valid:!1,path:n,error:"Config file not found."})):console.error(`Config file not found: ${n}`),{success:!1,message:"Config file not found."};let o;try{o=(0,vr.parse)(r)}catch(i){let l=i instanceof Error?i.message:"Unknown error";return s.json?console.log(JSON.stringify({valid:!1,path:n,error:`Invalid YAML syntax: ${l}`})):(console.error(`Failed to parse YAML at ${n}:`),console.error(` ${l}`)),{success:!1,message:"Invalid YAML syntax."}}let a=qe.safeParse(o);if(!a.success){if(s.json)console.log(JSON.stringify({valid:!1,path:n,errors:a.error.issues.map(i=>({path:i.path.length>0?i.path.join("."):"(root)",message:i.message}))}));else{console.error(`Config validation failed for ${n}:`);for(let i of a.error.issues){let l=i.path.length>0?i.path.join("."):"(root)";console.error(` - ${l}: ${i.message}`)}}return{success:!1,message:"Config validation failed."}}return s.json?console.log(JSON.stringify({valid:!0,path:n})):console.log(`Config is valid: ${n}`),{success:!0,message:"Config is valid."}}})});var bs={};x(bs,{projectsListCommand:()=>Ii});var Ri,Ii,js=f(()=>{"use strict";C();De();Xe();se();Vt();ne();be();Ri=t=>{switch(t){case"running":return"\u{1F7E2}";case"stopped":return"\u25EF";default:return""}},Ii=new b({name:"projects",description:"List all projects on the system",usage:"projects [list] [--with-config]",example:"projects --json",args:[],flags:[{name:"with-config",description:"Only show projects with a .denvig.yml configuration file",required:!1,type:"boolean",defaultValue:!1}],handler:async({flags:t})=>{let e=t["with-config"],s=T({withConfig:e});if(s.length===0)return t.json?console.log(JSON.stringify([])):console.log("No projects found."),{success:!0,message:"No projects found."};if(t.json){let i=[];for(let c of s){let p=new k(c.path),d=await Ae(p,{includeServiceStatus:!1}),{serviceStatus:u,...m}=d;i.push(m)}let l=i.sort((c,p)=>c.path.localeCompare(p.path));return console.log(JSON.stringify(l)),{success:!0,message:"Projects listed successfully."}}let n=await O.list("denvig."),r=[];for(let i of s){let l=new k(i.path),c=await Ae(l,{launchctlList:n});r.push(c)}let o=r.sort((i,l)=>i.path.localeCompare(l.path)),a=Z({columns:[{header:"",accessor:i=>Ri(i.serviceStatus)},{header:"ID",accessor:i=>he(i.id)},{header:"Name",accessor:i=>i.config?.name||i.slug},{header:"Path",accessor:i=>K(i.path)}],data:o});for(let i of a)console.log(i);return console.log(""),console.log(`${r.length} project${r.length===1?"":"s"} found`),{success:!0,message:"Projects listed successfully."}}})});var jr={};x(jr,{zshCompletionsCommand:()=>Ti});var $e,br,Ps,yr,Ti,Pr=f(()=>{"use strict";$e=I(require("fs"),1),br=I(require("os"),1),Ps=I(require("path"),1);C();yr=`#compdef denvig
53
53
 
54
54
  _denvig() {
55
55
  local -a completions
@@ -64,5 +64,5 @@ _denvig() {
64
64
  }
65
65
 
66
66
  _denvig "$@"
67
- `,Ii=new b({name:"zsh:completions",description:"Output zsh completion script",usage:"zsh completions [--install]",example:"denvig zsh completions --install",args:[],flags:[{name:"install",description:"Install completions to ~/.zsh/completions/_denvig",required:!1,type:"boolean",defaultValue:!1}],handler:({flags:t})=>{if(t.install){let e=yr.homedir(),s=js.join(e,".zsh","completions"),n=js.join(s,"_denvig");return Ce.existsSync(s)||Ce.mkdirSync(s,{recursive:!0}),Ce.writeFileSync(n,vr),console.log(`Installed completions to ${n}`),{success:!0}}return console.log(vr),{success:!0}}})});var Pr,Sr=f(()=>{"use strict";Pr=async()=>{let{runCommand:t}=await Promise.resolve().then(()=>(Rt(),Lt)),{configCommand:e}=await Promise.resolve().then(()=>(Tt(),It)),{pluginsCommand:s}=await Promise.resolve().then(()=>(Ft(),At)),{versionCommand:n}=await Promise.resolve().then(()=>(Et(),_t)),{infoCommand:r}=await Promise.resolve().then(()=>(Jt(),Vt)),{servicesCommand:o}=await Promise.resolve().then(()=>(qt(),Gt)),{servicesStartCommand:a}=await Promise.resolve().then(()=>(Ht(),zt)),{servicesStopCommand:i}=await Promise.resolve().then(()=>(Bt(),Ut)),{servicesRestartCommand:l}=await Promise.resolve().then(()=>(Kt(),Yt)),{servicesStatusCommand:c}=await Promise.resolve().then(()=>(Qt(),Zt)),{logsCommand:p}=await Promise.resolve().then(()=>(es(),Xt)),{servicesTeardownCommand:d}=await Promise.resolve().then(()=>(ns(),ss)),{depsListCommand:u}=await Promise.resolve().then(()=>(ps(),ls)),{depsOutdatedCommand:m}=await Promise.resolve().then(()=>(ds(),ms)),{depsWhyCommand:v}=await Promise.resolve().then(()=>(fs(),gs)),{configVerifyCommand:g}=await Promise.resolve().then(()=>(vs(),hs)),{projectsListCommand:y}=await Promise.resolve().then(()=>(bs(),ys));return{run:t,config:e,"config:verify":g,plugins:s,version:n,info:r,services:o,"services:start":a,"services:stop":i,"services:restart":l,"services:status":c,"services:logs":p,"services:teardown":d,deps:u,"deps:list":u,"deps:outdated":m,"deps:why":v,projects:y,"projects:list":y}}});var ot,Dr,wr=f(()=>{"use strict";ot=["config","deps","info","outdated","plugins","projects","run","services","version","zsh"],Dr={services:["start","stop","restart","status","logs","teardown"],deps:["list","outdated","why"],config:["verify"],projects:["list"],zsh:["completions","__complete__"]}});var Cr,$r,xr=f(()=>{"use strict";se();ne();Cr=(t="")=>{if(t.startsWith("/")||t.startsWith("~"))return[];let e=T();if(t.startsWith("id:")){let s=t.slice(3);return e.map(n=>{let r=new k(n.path);return`id:${fe(r.id)}`}).filter(n=>n.startsWith(t))}return e.map(s=>s.slug.replace(/^(github|local):/,"")).filter(s=>s.startsWith(t))},$r=t=>{let e=t[t.length-1]||"";return e.startsWith("--project=")?e.slice(10):t.length>=2&&t[t.length-2]==="--project"?e:null}});var kr,Or=f(()=>{"use strict";wr();xr();kr=async(t,e)=>{let s=$r(t);if(s!==null)return Cr(s);if(t.length===1)return[...ot];let n=t[1],r=Dr[n];if(t.length===2){if(r)return[...r];if(ot.includes(n)&&e?.commands&&e?.project){let o=e.commands[n];return o?.completions?await o.completions({project:e.project},[]):[]}return ot.filter(o=>o.startsWith(n))}if(t.length===3&&r){let o=t[2];if(r.includes(o)){let a=`${n}:${o}`,i=e?.commands[a];return i?.completions&&e?.project?await i.completions({project:e.project},[]):[]}return r.filter(a=>a.startsWith(o))}if(e?.commands&&e?.project){let o,a;if(r){let i=t[2],l=`${n}:${i}`;o=e.commands[l],a=t.slice(3)}else o=e.commands[n],a=t.slice(2);if(o?.completions){let i=await o.completions({project:e.project},a),l=a[a.length-1]||"";return l?i.filter(c=>c.startsWith(l)):i}}return[]}});var Nr={};x(Nr,{zshCompleteCommand:()=>Ti});var Ti,Lr=f(()=>{"use strict";C();Sr();Or();Ti=new b({name:"zsh:__complete__",description:"Handle zsh completion requests (internal)",usage:"zsh __complete__ -- <words...>",example:"denvig zsh __complete__ -- denvig services",args:[],flags:[],handler:async({project:t,extraArgs:e=[]})=>{let s=e,n=await Pr(),r=await kr(s,{project:t,commands:n});for(let o of r)console.log(o.replace(/:/g,"\\:"));return{success:!0}}})});var it=I(require("minimist"),1);ke();var Me=[{name:"project",description:"The project slug to run against. Defaults to current directory.",required:!1,type:"string",defaultValue:void 0},{name:"json",description:"Output in JSON format",required:!1,type:"boolean",defaultValue:!1}],Kr=new Set(["internals:resource-hash","internals:resource-id","zsh:__complete__","deps","projects"]);function Zr(t){let e=[];e.push(`Denvig v${z()}`),e.push(""),e.push("Commands:");let s=Object.keys(t).filter(a=>!Kr.has(a)&&!a.startsWith("internals:")),n=s.map(a=>`denvig ${t[a].usage}`),o=Math.max(...n.map(a=>a.length))+2;for(let a of s){let i=`denvig ${t[a].usage}`;e.push(` ${i.padEnd(o," ")} ${t[a].description}`)}return e.push(""),e.push("Options:"),e.push(" -h, --help Show help"),e.push(" -v, --version Show version number"),e}function mt(t){for(let e of Zr(t))console.log(e)}function Qr(t,e=Me){let s=[];if(s.push(`Usage: denvig ${t.usage}`),s.push(""),s.push(t.description),t.args.length>0){s.push(""),s.push("Arguments:");for(let r of t.args){let o=r.required?"":" (optional)";s.push(` ${r.name}${o}`),s.push(` ${r.description}`)}}let n=[...e,...t.flags];if(n.length>0){s.push(""),s.push("Options:");let r=n.map(i=>`--${i.name}`),a=Math.max(...r.map(i=>i.length))+2;for(let i of n){let l=`--${i.name}`;s.push(` ${l.padEnd(a," ")} ${i.description}`)}}if(t.example){s.push(""),s.push("Example:");let r=t.example.startsWith("denvig ")?t.example:`denvig ${t.example}`;s.push(` ${r}`)}return s}function xs(t,e=Me){for(let s of Qr(t,e))console.log(s)}var Je=require("fs/promises"),ks=require("os"),Ve=require("path"),Xr=()=>process.env.DENVIG_CLI_LOGS_ENABLED!=="0",Os=()=>process.env.DENVIG_CLI_LOGS_PATH?(0,Ve.resolve)(process.env.DENVIG_CLI_LOGS_PATH):(0,Ve.resolve)((0,ks.homedir)(),".denvig","logs","cli.jsonl"),eo=async()=>{let t=Os(),e=(0,Ve.resolve)(t,"..");await(0,Je.mkdir)(e,{recursive:!0})},to=async t=>{if(Xr())try{await eo();let e=Os(),s=`${JSON.stringify(t)}
68
- `;await(0,Je.appendFile)(e,s,"utf-8")}catch{}},Ns=t=>{let e=Date.now();return{finish:async(s,n)=>{let r={timestamp:new Date().toISOString(),version:t.version,slug:void 0,command:t.command,via:void 0,duration:Date.now()-e,path:t.path,status:s,error:void 0};t.slug!==void 0&&(r.slug=t.slug),t.via!==void 0&&(r.via=t.via),n!==void 0&&(r.error=n),await to(r)}}};ce();ze();se();Nt();ne();ke();async function Ai(){let t=process.argv[2],e=process.argv.slice(2),s=(0,it.default)(e);(s.version||s.v)&&(console.log(`v${z()}`),process.exit(0));let n=ie(),r=process.cwd(),o=(0,it.default)(process.argv.slice(2)).project?.toString(),a=null;if(o)a=An(o,oe).path;else{let R=T().find(J=>r===J.path||r.startsWith(`${J.path}/`));R?a=R.path:a=r}let i=a?new k(a):null,l=a?yt(a):null,c=Ns({version:z(),command:`denvig ${process.argv.slice(2).join(" ")}`,slug:l??void 0,path:process.cwd(),via:process.env.DENVIG_CLI_VIA}),p={outdated:"deps:outdated"};p[t]&&(t=p[t]);let d=["start","stop","restart","status","logs","teardown"];if(t==="services"){let h=process.argv[3];h&&d.includes(h)&&(t=`services:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let u=["list","outdated","why"];if(t==="deps"){let h=process.argv[3];h&&u.includes(h)&&(t=`deps:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let m=["verify"];if(t==="config"){let h=process.argv[3];h&&m.includes(h)&&(t=`config:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let v=["list"];if(t==="projects"){let h=process.argv[3];h&&v.includes(h)&&(t=`projects:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let g=["completions","__complete__"];if(t==="zsh"){let h=process.argv[3];h&&g.includes(h)&&(t=`zsh:${h}`,e=[process.argv[2],...process.argv.slice(4)])}[...n.quickActions??[],...i?.config?.quickActions??[]].sort().includes(t)&&(e=["run",...process.argv.slice(2)],t="run",console.log("> Proxying to denvig run",...process.argv.slice(2)));let{runCommand:j}=await Promise.resolve().then(()=>(Rt(),Lt)),{configCommand:P}=await Promise.resolve().then(()=>(Tt(),It)),{pluginsCommand:D}=await Promise.resolve().then(()=>(Ft(),At)),{versionCommand:$}=await Promise.resolve().then(()=>(Et(),_t)),{infoCommand:V}=await Promise.resolve().then(()=>(Jt(),Vt)),{servicesCommand:q}=await Promise.resolve().then(()=>(qt(),Gt)),{servicesStartCommand:H}=await Promise.resolve().then(()=>(Ht(),zt)),{servicesStopCommand:$e}=await Promise.resolve().then(()=>(Bt(),Ut)),{servicesRestartCommand:xe}=await Promise.resolve().then(()=>(Kt(),Yt)),{servicesStatusCommand:Fe}=await Promise.resolve().then(()=>(Qt(),Zt)),{logsCommand:_e}=await Promise.resolve().then(()=>(es(),Xt)),{servicesTeardownCommand:Rr}=await Promise.resolve().then(()=>(ns(),ss)),{internalsResourceHashCommand:Ir,internalsResourceIdCommand:Tr}=await Promise.resolve().then(()=>(ir(),or)),{depsListCommand:Ps}=await Promise.resolve().then(()=>(ps(),ls)),{depsOutdatedCommand:Ar}=await Promise.resolve().then(()=>(ds(),ms)),{depsWhyCommand:Fr}=await Promise.resolve().then(()=>(fs(),gs)),{configVerifyCommand:_r}=await Promise.resolve().then(()=>(vs(),hs)),{projectsListCommand:Ss}=await Promise.resolve().then(()=>(bs(),ys)),{zshCompletionsCommand:Er}=await Promise.resolve().then(()=>(jr(),br)),{zshCompleteCommand:Wr}=await Promise.resolve().then(()=>(Lr(),Nr)),re={run:j,config:P,"config:verify":_r,plugins:D,version:$,info:V,services:q,"services:start":H,"services:stop":$e,"services:restart":xe,"services:status":Fe,"services:logs":_e,"services:teardown":Rr,deps:Ps,"deps:list":Ps,"deps:outdated":Ar,"deps:why":Fr,"internals:resource-hash":Ir,"internals:resource-id":Tr,projects:Ss,"projects:list":Ss,"zsh:completions":Er,"zsh:__complete__":Wr},Ee=re[t],X=(0,it.default)(e),ct=X.help||X.h,Ds={},at=null;for(let[h,R]of(Ee?.args||[]).entries()){let J=X._[h+1];if(J!==void 0)Ds[R.name]=J;else if(R.required){at=R.name;break}}if(at&&!ct){let h=`Missing required argument: ${at}`;console.error(h),await c.finish(1,h),process.exit(1)}let Mr=X._.slice(Ee?.args.length+1).map(h=>String(h))||[],ws=[...Me,...Ee?.flags||[]],Vr=new Set(ws.map(h=>h.name)),lt={},pt=null;for(let h of ws)if(X[h.name]!==void 0)lt[h.name]=X[h.name];else if(h.defaultValue!==void 0)lt[h.name]=h.defaultValue;else if(h.required){pt=h.name;break}if(pt&&!ct){let h=`Missing required flag: ${pt}`;console.error(h),await c.finish(1,h),process.exit(1)}let We=[];for(let[h,R]of Object.entries(X))h!=="_"&&!Vr.has(h)&&(R===!0?We.push(`--${h}`):R===!1?We.push(`--no-${h}`):We.push(`--${h}`,String(R)));let Jr=[...Mr,...We];if(t||(mt(re),await c.finish(1,"No command provided"),process.exit(1)),(s.help||s.h)&&!re[t]&&(mt(re),await c.finish(0,"Showed help"),process.exit(0)),!re[t]){let h=`Command "${t}" not found`;console.error(`${h}.`),await c.finish(1,h),process.exit(1)}ct&&(xs(re[t]),await c.finish(0,"Showed command help"),process.exit(0));try{if(!i){let J="No project provided or detected";console.error(`${J}.`),await c.finish(1,J),process.exit(1)}let{success:h,message:R}=await Ee.run(i,Ds,lt,Jr);if(!h){let J=(R||"Command failed").replace(/[\r\n]+/g," ").trim();await c.finish(1,J),process.exit(1)}await c.finish(0)}catch(h){let R=(h instanceof Error?h.message:"Unknown error").replace(/[\r\n]+/g," ").trim();console.error(`Error executing command "${t}":`,h),await c.finish(1,R),process.exit(1)}}Ai();
67
+ `,Ti=new b({name:"zsh:completions",description:"Output zsh completion script",usage:"zsh completions [--install]",example:"denvig zsh completions --install",args:[],flags:[{name:"install",description:"Install completions to ~/.zsh/completions/_denvig",required:!1,type:"boolean",defaultValue:!1}],handler:({flags:t})=>{if(t.install){let e=br.homedir(),s=Ps.join(e,".zsh","completions"),n=Ps.join(s,"_denvig");return $e.existsSync(s)||$e.mkdirSync(s,{recursive:!0}),$e.writeFileSync(n,yr),console.log(`Installed completions to ${n}`),{success:!0}}return console.log(yr),{success:!0}}})});var Sr,Dr=f(()=>{"use strict";Sr=async()=>{let{runCommand:t}=await Promise.resolve().then(()=>(It(),Rt)),{configCommand:e}=await Promise.resolve().then(()=>(At(),Tt)),{pluginsCommand:s}=await Promise.resolve().then(()=>(_t(),Ft)),{versionCommand:n}=await Promise.resolve().then(()=>(Wt(),Et)),{infoCommand:r}=await Promise.resolve().then(()=>(Gt(),Jt)),{servicesCommand:o}=await Promise.resolve().then(()=>(zt(),qt)),{servicesStartCommand:a}=await Promise.resolve().then(()=>(Ht(),Ut)),{servicesStopCommand:i}=await Promise.resolve().then(()=>(Yt(),Bt)),{servicesRestartCommand:l}=await Promise.resolve().then(()=>(Zt(),Kt)),{servicesStatusCommand:c}=await Promise.resolve().then(()=>(Xt(),Qt)),{logsCommand:p}=await Promise.resolve().then(()=>(ts(),es)),{servicesTeardownCommand:d}=await Promise.resolve().then(()=>(rs(),ns)),{depsListCommand:u}=await Promise.resolve().then(()=>(us(),ps)),{depsOutdatedCommand:m}=await Promise.resolve().then(()=>(gs(),ds)),{depsWhyCommand:v}=await Promise.resolve().then(()=>(hs(),fs)),{configVerifyCommand:g}=await Promise.resolve().then(()=>(ys(),vs)),{projectsListCommand:y}=await Promise.resolve().then(()=>(js(),bs));return{run:t,config:e,"config:verify":g,plugins:s,version:n,info:r,services:o,"services:start":a,"services:stop":i,"services:restart":l,"services:status":c,"services:logs":p,"services:teardown":d,deps:u,"deps:list":u,"deps:outdated":m,"deps:why":v,projects:y,"projects:list":y}}});var it,wr,Cr=f(()=>{"use strict";it=["config","deps","info","outdated","plugins","projects","run","services","version","zsh"],wr={services:["start","stop","restart","status","logs","teardown"],deps:["list","outdated","why"],config:["verify"],projects:["list"],zsh:["completions","__complete__"]}});var $r,xr,kr=f(()=>{"use strict";se();ne();$r=(t="")=>{if(t.startsWith("/")||t.startsWith("~"))return[];let e=T();if(t.startsWith("id:")){let s=t.slice(3);return e.map(n=>{let r=new k(n.path);return`id:${he(r.id)}`}).filter(n=>n.startsWith(t))}return e.map(s=>s.slug.replace(/^(github|local):/,"")).filter(s=>s.startsWith(t))},xr=t=>{let e=t[t.length-1]||"";return e.startsWith("--project=")?e.slice(10):t.length>=2&&t[t.length-2]==="--project"?e:null}});var Or,Nr=f(()=>{"use strict";Cr();kr();Or=async(t,e)=>{let s=xr(t);if(s!==null)return $r(s);if(t.length===1)return[...it];let n=t[1],r=wr[n];if(t.length===2){if(r)return[...r];if(it.includes(n)&&e?.commands&&e?.project){let o=e.commands[n];return o?.completions?await o.completions({project:e.project},[]):[]}return it.filter(o=>o.startsWith(n))}if(t.length===3&&r){let o=t[2];if(r.includes(o)){let a=`${n}:${o}`,i=e?.commands[a];return i?.completions&&e?.project?await i.completions({project:e.project},[]):[]}return r.filter(a=>a.startsWith(o))}if(e?.commands&&e?.project){let o,a;if(r){let i=t[2],l=`${n}:${i}`;o=e.commands[l],a=t.slice(3)}else o=e.commands[n],a=t.slice(2);if(o?.completions){let i=await o.completions({project:e.project},a),l=a[a.length-1]||"";return l?i.filter(c=>c.startsWith(l)):i}}return[]}});var Lr={};x(Lr,{zshCompleteCommand:()=>Ai});var Ai,Rr=f(()=>{"use strict";C();Dr();Nr();Ai=new b({name:"zsh:__complete__",description:"Handle zsh completion requests (internal)",usage:"zsh __complete__ -- <words...>",example:"denvig zsh __complete__ -- denvig services",args:[],flags:[],handler:async({project:t,extraArgs:e=[]})=>{let s=e,n=await Sr(),r=await Or(s,{project:t,commands:n});for(let o of r)console.log(o.replace(/:/g,"\\:"));return{success:!0}}})});var ct=I(require("minimist"),1);Oe();var Ve=[{name:"project",description:"The project slug to run against. Defaults to current directory.",required:!1,type:"string",defaultValue:void 0},{name:"json",description:"Output in JSON format",required:!1,type:"boolean",defaultValue:!1}],Zr=new Set(["internals:resource-hash","internals:resource-id","zsh:__complete__","deps","projects"]);function Qr(t){let e=[];e.push(`Denvig v${z()}`),e.push(""),e.push("Commands:");let s=Object.keys(t).filter(a=>!Zr.has(a)&&!a.startsWith("internals:")),n=s.map(a=>`denvig ${t[a].usage}`),o=Math.max(...n.map(a=>a.length))+2;for(let a of s){let i=`denvig ${t[a].usage}`;e.push(` ${i.padEnd(o," ")} ${t[a].description}`)}return e.push(""),e.push("Options:"),e.push(" -h, --help Show help"),e.push(" -v, --version Show version number"),e}function dt(t){for(let e of Qr(t))console.log(e)}function Xr(t,e=Ve){let s=[];if(s.push(`Usage: denvig ${t.usage}`),s.push(""),s.push(t.description),t.args.length>0){s.push(""),s.push("Arguments:");for(let r of t.args){let o=r.required?"":" (optional)";s.push(` ${r.name}${o}`),s.push(` ${r.description}`)}}let n=[...e,...t.flags];if(n.length>0){s.push(""),s.push("Options:");let r=n.map(i=>`--${i.name}`),a=Math.max(...r.map(i=>i.length))+2;for(let i of n){let l=`--${i.name}`;s.push(` ${l.padEnd(a," ")} ${i.description}`)}}if(t.example){s.push(""),s.push("Example:");let r=t.example.startsWith("denvig ")?t.example:`denvig ${t.example}`;s.push(` ${r}`)}return s}function ks(t,e=Ve){for(let s of Xr(t,e))console.log(s)}var Ge=require("fs/promises"),Os=require("os"),Je=require("path"),eo=()=>process.env.DENVIG_CLI_LOGS_ENABLED!=="0",Ns=()=>process.env.DENVIG_CLI_LOGS_PATH?(0,Je.resolve)(process.env.DENVIG_CLI_LOGS_PATH):(0,Je.resolve)((0,Os.homedir)(),".denvig","logs","cli.jsonl"),to=async()=>{let t=Ns(),e=(0,Je.resolve)(t,"..");await(0,Ge.mkdir)(e,{recursive:!0})},so=async t=>{if(eo())try{await to();let e=Ns(),s=`${JSON.stringify(t)}
68
+ `;await(0,Ge.appendFile)(e,s,"utf-8")}catch{}},Ls=t=>{let e=Date.now();return{finish:async(s,n)=>{let r={timestamp:new Date().toISOString(),version:t.version,slug:void 0,command:t.command,via:void 0,duration:Date.now()-e,path:t.path,status:s,error:void 0};t.slug!==void 0&&(r.slug=t.slug),t.via!==void 0&&(r.via=t.via),n!==void 0&&(r.error=n),await so(r)}}};ae();Ue();se();Lt();ne();Oe();async function Fi(){let t=process.argv[2],e=process.argv.slice(2),s=(0,ct.default)(e);(s.version||s.v)&&(console.log(`v${z()}`),process.exit(0));let n=ce(),r=process.cwd(),o=(0,ct.default)(process.argv.slice(2)).project?.toString(),a=null;if(o)a=Fn(o,ie).path;else{let R=T().find(J=>r===J.path||r.startsWith(`${J.path}/`));R?a=R.path:a=r}let i=a?new k(a):null,l=a?bt(a):null,c=Ls({version:z(),command:`denvig ${process.argv.slice(2).join(" ")}`,slug:l??void 0,path:process.cwd(),via:process.env.DENVIG_CLI_VIA}),p={outdated:"deps:outdated"};p[t]&&(t=p[t]);let d=["start","stop","restart","status","logs","teardown"];if(t==="services"){let h=process.argv[3];h&&d.includes(h)&&(t=`services:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let u=["list","outdated","why"];if(t==="deps"){let h=process.argv[3];h&&u.includes(h)&&(t=`deps:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let m=["verify"];if(t==="config"){let h=process.argv[3];h&&m.includes(h)&&(t=`config:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let v=["list"];if(t==="projects"){let h=process.argv[3];h&&v.includes(h)&&(t=`projects:${h}`,e=[process.argv[2],...process.argv.slice(4)])}let g=["completions","__complete__"];if(t==="zsh"){let h=process.argv[3];h&&g.includes(h)&&(t=`zsh:${h}`,e=[process.argv[2],...process.argv.slice(4)])}[...n.quickActions??[],...i?.config?.quickActions??[]].sort().includes(t)&&(e=["run",...process.argv.slice(2)],t="run",console.log("> Proxying to denvig run",...process.argv.slice(2)));let{runCommand:j}=await Promise.resolve().then(()=>(It(),Rt)),{configCommand:P}=await Promise.resolve().then(()=>(At(),Tt)),{pluginsCommand:D}=await Promise.resolve().then(()=>(_t(),Ft)),{versionCommand:$}=await Promise.resolve().then(()=>(Wt(),Et)),{infoCommand:V}=await Promise.resolve().then(()=>(Gt(),Jt)),{servicesCommand:q}=await Promise.resolve().then(()=>(zt(),qt)),{servicesStartCommand:U}=await Promise.resolve().then(()=>(Ht(),Ut)),{servicesStopCommand:xe}=await Promise.resolve().then(()=>(Yt(),Bt)),{servicesRestartCommand:ke}=await Promise.resolve().then(()=>(Zt(),Kt)),{servicesStatusCommand:_e}=await Promise.resolve().then(()=>(Xt(),Qt)),{logsCommand:Ee}=await Promise.resolve().then(()=>(ts(),es)),{servicesTeardownCommand:Ir}=await Promise.resolve().then(()=>(rs(),ns)),{internalsResourceHashCommand:Tr,internalsResourceIdCommand:Ar}=await Promise.resolve().then(()=>(cr(),ir)),{depsListCommand:Ss}=await Promise.resolve().then(()=>(us(),ps)),{depsOutdatedCommand:Fr}=await Promise.resolve().then(()=>(gs(),ds)),{depsWhyCommand:_r}=await Promise.resolve().then(()=>(hs(),fs)),{configVerifyCommand:Er}=await Promise.resolve().then(()=>(ys(),vs)),{projectsListCommand:Ds}=await Promise.resolve().then(()=>(js(),bs)),{zshCompletionsCommand:Wr}=await Promise.resolve().then(()=>(Pr(),jr)),{zshCompleteCommand:Mr}=await Promise.resolve().then(()=>(Rr(),Lr)),oe={run:j,config:P,"config:verify":Er,plugins:D,version:$,info:V,services:q,"services:start":U,"services:stop":xe,"services:restart":ke,"services:status":_e,"services:logs":Ee,"services:teardown":Ir,deps:Ss,"deps:list":Ss,"deps:outdated":Fr,"deps:why":_r,"internals:resource-hash":Tr,"internals:resource-id":Ar,projects:Ds,"projects:list":Ds,"zsh:completions":Wr,"zsh:__complete__":Mr},We=oe[t],X=(0,ct.default)(e),at=X.help||X.h,ws={},lt=null;for(let[h,R]of(We?.args||[]).entries()){let J=X._[h+1];if(J!==void 0)ws[R.name]=J;else if(R.required){lt=R.name;break}}if(lt&&!at){let h=`Missing required argument: ${lt}`;console.error(h),await c.finish(1,h),process.exit(1)}let Vr=X._.slice(We?.args.length+1).map(h=>String(h))||[],Cs=[...Ve,...We?.flags||[]],Jr=new Set(Cs.map(h=>h.name)),pt={},ut=null;for(let h of Cs)if(X[h.name]!==void 0)pt[h.name]=X[h.name];else if(h.defaultValue!==void 0)pt[h.name]=h.defaultValue;else if(h.required){ut=h.name;break}if(ut&&!at){let h=`Missing required flag: ${ut}`;console.error(h),await c.finish(1,h),process.exit(1)}let Me=[];for(let[h,R]of Object.entries(X))h!=="_"&&!Jr.has(h)&&(R===!0?Me.push(`--${h}`):R===!1?Me.push(`--no-${h}`):Me.push(`--${h}`,String(R)));let Gr=[...Vr,...Me];if(t||(dt(oe),await c.finish(1,"No command provided"),process.exit(1)),(s.help||s.h)&&!oe[t]&&(dt(oe),await c.finish(0,"Showed help"),process.exit(0)),!oe[t]){let h=`Command "${t}" not found`;console.error(`${h}.`),await c.finish(1,h),process.exit(1)}at&&(ks(oe[t]),await c.finish(0,"Showed command help"),process.exit(0));try{if(!i){let J="No project provided or detected";console.error(`${J}.`),await c.finish(1,J),process.exit(1)}let{success:h,message:R}=await We.run(i,ws,pt,Gr);if(!h){let J=(R||"Command failed").replace(/[\r\n]+/g," ").trim();await c.finish(1,J),process.exit(1)}await c.finish(0)}catch(h){let R=(h instanceof Error?h.message:"Unknown error").replace(/[\r\n]+/g," ").trim();console.error(`Error executing command "${t}":`,h),await c.finish(1,R),process.exit(1)}}Fi();
package/dist/sdk.d.cts CHANGED
@@ -25,13 +25,13 @@ declare const ProjectConfigSchema: z.ZodObject<{
25
25
  port: z.ZodOptional<z.ZodNumber>;
26
26
  domain: z.ZodOptional<z.ZodString>;
27
27
  secure: z.ZodOptional<z.ZodBoolean>;
28
- }, z.core.$strict>>;
28
+ }, z.core.$strip>>;
29
29
  envFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
30
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
31
31
  keepAlive: z.ZodOptional<z.ZodBoolean>;
32
32
  startOnBoot: z.ZodOptional<z.ZodBoolean>;
33
- }, z.core.$strict>>>;
34
- }, z.core.$strict>;
33
+ }, z.core.$strip>>>;
34
+ }, z.core.$strip>;
35
35
  type ProjectConfigSchema = z.infer<typeof ProjectConfigSchema>;
36
36
 
37
37
  type ServiceStatus$1 = 'running' | 'stopped' | 'none';
package/dist/sdk.d.ts CHANGED
@@ -25,13 +25,13 @@ declare const ProjectConfigSchema: z.ZodObject<{
25
25
  port: z.ZodOptional<z.ZodNumber>;
26
26
  domain: z.ZodOptional<z.ZodString>;
27
27
  secure: z.ZodOptional<z.ZodBoolean>;
28
- }, z.core.$strict>>;
28
+ }, z.core.$strip>>;
29
29
  envFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
30
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
31
31
  keepAlive: z.ZodOptional<z.ZodBoolean>;
32
32
  startOnBoot: z.ZodOptional<z.ZodBoolean>;
33
- }, z.core.$strict>>>;
34
- }, z.core.$strict>;
33
+ }, z.core.$strip>>>;
34
+ }, z.core.$strip>;
35
35
  type ProjectConfigSchema = z.infer<typeof ProjectConfigSchema>;
36
36
 
37
37
  type ServiceStatus$1 = 'running' | 'stopped' | 'none';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "denvig",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "license": "MIT",
5
5
  "description": "A CLI tool to consistently manage cross-discipline projects",
6
6
  "bin": {
@@ -40,12 +40,12 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "minimist": "^1.2.8",
43
- "semver": "^7.7.3",
43
+ "semver": "^7.7.4",
44
44
  "yaml": "^2.8.2",
45
45
  "zod": "^4.3.6"
46
46
  },
47
47
  "devDependencies": {
48
- "@biomejs/biome": "^2.3.12",
48
+ "@biomejs/biome": "^2.3.14",
49
49
  "@types/minimist": "^1.2.5",
50
50
  "@types/node": "^24",
51
51
  "@types/semver": "^7.7.1",