@stacksjs/launchpad
Version:
Like Homebrew, but faster.
406 lines (350 loc) • 65.5 kB
JavaScript
// @bun
import{va as y}from"./chunk-6qxbw28k.js";import{Ta as S,Va as GG}from"./chunk-wkk6vc0r.js";import"./chunk-f8dcmgkp.js";import"./chunk-fhet42vs.js";import{ab as H}from"./chunk-b9hx8gsj.js";import{bb as q,cb as F}from"./chunk-8pxdwzvm.js";import{spawn as E}from"child_process";import O from"fs";import{platform as b}from"os";import R from"path";import U from"process";import{homedir as Z}from"os";import $ from"path";var p={postgres:{name:"postgres",displayName:"PostgreSQL",description:"PostgreSQL database server",packageDomain:"postgresql.org",executable:"postgres",args:["-D","{dataDir}","-p","{port}","-c","listen_addresses=127.0.0.1"],env:{PGDATA:"{dataDir}"},dataDirectory:$.join(Z(),".local","share","launchpad","services","postgres","data"),logFile:$.join(Z(),".local","share","launchpad","logs","postgres.log"),pidFile:$.join(Z(),".local","share","launchpad","services","postgres","postgres.pid"),port:5432,dependencies:["openssl.org^1.0.1","gnu.org/readline","zlib.net","lz4.org","gnome.org/libxml2~2.13","gnome.org/libxslt","unicode.org^73"],healthCheck:{command:["pg_isready","-h","127.0.0.1","-p","5432"],expectedExitCode:0,timeout:5,interval:30,retries:3},initCommand:["initdb","-D","{dataDir}","--auth-local={authMethod}","--auth-host={authMethod}","--encoding=UTF8"],postStartCommands:[["createdb","-h","127.0.0.1","-p","5432","{projectDatabase}"],["psql","-h","127.0.0.1","-p","5432","-d","postgres","-c","DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'postgres') THEN CREATE ROLE postgres SUPERUSER LOGIN; END IF; END $$;"],["psql","-h","127.0.0.1","-p","5432","-d","postgres","-c","DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '{appUser}') THEN CREATE ROLE {appUser} LOGIN PASSWORD '{appPassword}'; ELSE ALTER ROLE {appUser} WITH PASSWORD '{appPassword}'; END IF; END $$;"],["psql","-h","127.0.0.1","-p","5432","-d","postgres","-c","ALTER DATABASE {projectDatabase} OWNER TO {appUser}; GRANT ALL PRIVILEGES ON DATABASE {projectDatabase} TO {appUser};"],["psql","-h","127.0.0.1","-p","5432","-d","postgres","-c","GRANT CREATE ON SCHEMA public TO {appUser};"],["psql","-h","127.0.0.1","-p","5432","-d","postgres","-c","GRANT USAGE ON SCHEMA public TO {appUser};"]],supportsGracefulShutdown:!0,config:{listen_addresses:"localhost",port:5432,max_connections:100,shared_buffers:"128MB",log_destination:"stderr",logging_collector:"on",log_directory:"log",log_filename:"postgresql-%Y-%m-%d_%H%M%S.log",log_statement:"none",log_line_prefix:"%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ",projectDatabase:"{projectName}",appUser:"{dbUsername}",appPassword:"{dbPassword}"}},php:{name:"php",displayName:"PHP",description:"PHP with database extensions (PostgreSQL, MySQL, SQLite)",packageDomain:"php.net",executable:"php",args:[],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","php"),configFile:$.join(Z(),".local","share","launchpad","services","php","php.ini"),dependencies:["postgresql.org/libpq"],supportsGracefulShutdown:!1,extensions:{pecl:{required:["pdo_pgsql","pgsql"],optional:["redis","memcached","imagick","xdebug"],buildDependencies:{pdo_pgsql:["postgresql.org/libpq"],pgsql:["postgresql.org/libpq"],redis:[],memcached:[],imagick:[]}}},config:{extensions:["pdo","pdo_sqlite","pdo_mysql","pdo_pgsql","mysqli","pgsql","sqlite3"],memory_limit:"512M",max_execution_time:300,upload_max_filesize:"64M",post_max_size:"64M",display_errors:"On",error_reporting:"E_ALL"}},mysql:{name:"mysql",displayName:"MySQL",description:"MySQL database server",packageDomain:"mysql.com",executable:"mysqld_safe",args:["--datadir={dataDir}","--pid-file={pidFile}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","mysql","data"),logFile:$.join(Z(),".local","share","launchpad","logs","mysql.log"),pidFile:$.join(Z(),".local","share","launchpad","services","mysql","mysql.pid"),port:3306,dependencies:[],healthCheck:{command:["mysqladmin","ping","-h","127.0.0.1","-P","3306"],expectedExitCode:0,timeout:5,interval:30,retries:3},initCommand:["mysqld","--initialize-insecure","--datadir={dataDir}","--user=mysql"],postStartCommands:[["mysql","-u","root","-e","CREATE DATABASE IF NOT EXISTS {projectDatabase};"],["mysql","-u","root","-e","CREATE USER IF NOT EXISTS '{dbUsername}'@'localhost' IDENTIFIED BY '{dbPassword}';"],["mysql","-u","root","-e","GRANT ALL PRIVILEGES ON {projectDatabase}.* TO '{dbUsername}'@'localhost';"],["mysql","-u","root","-e","FLUSH PRIVILEGES;"]],supportsGracefulShutdown:!0,config:{bind_address:"127.0.0.1",port:3306,max_connections:100,innodb_buffer_pool_size:"128M",query_cache_size:"32M",tmp_table_size:"32M",max_heap_table_size:"32M",projectDatabase:"{projectName}",appUser:"{dbUsername}",appPassword:"{dbPassword}"}},redis:{name:"redis",displayName:"Redis",description:"Redis in-memory data store",packageDomain:"redis.io",executable:"redis-server",args:["{configFile}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","redis","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","redis.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","redis.log"),pidFile:$.join(Z(),".local","share","launchpad","services","redis","redis.pid"),port:6379,dependencies:[],healthCheck:{command:["redis-cli","ping"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},nginx:{name:"nginx",displayName:"Nginx",description:"Nginx web server",packageDomain:"nginx.org",executable:"nginx",args:["-c","{configFile}","-g","daemon off;"],env:{},configFile:$.join(Z(),".local","share","launchpad","services","config","nginx.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","nginx.log"),pidFile:$.join(Z(),".local","share","launchpad","services","nginx","nginx.pid"),port:8080,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8080/health"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},memcached:{name:"memcached",displayName:"Memcached",description:"Memcached memory object caching system",packageDomain:"memcached.org",executable:"memcached",args:["-p","11211","-m","64","-c","1024"],env:{},port:11211,dependencies:[],healthCheck:{command:["nc","-z","localhost","11211"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},mongodb:{name:"mongodb",displayName:"MongoDB",description:"MongoDB document database",packageDomain:"mongodb.com",executable:"mongod",args:["--dbpath","{dataDir}","--port","27017"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","mongodb","data"),logFile:$.join(Z(),".local","share","launchpad","logs","mongodb.log"),pidFile:$.join(Z(),".local","share","launchpad","services","mongodb","mongodb.pid"),port:27017,dependencies:[],healthCheck:{command:["mongo","--eval",'db.runCommand("ping")',"--quiet"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},rabbitmq:{name:"rabbitmq",displayName:"RabbitMQ",description:"RabbitMQ message broker",packageDomain:"rabbitmq.com",executable:"rabbitmq-server",args:[],env:{RABBITMQ_MNESIA_BASE:$.join(Z(),".local","share","launchpad","services","rabbitmq","mnesia"),RABBITMQ_LOG_BASE:$.join(Z(),".local","share","launchpad","logs")},dataDirectory:$.join(Z(),".local","share","launchpad","services","rabbitmq","mnesia"),logFile:$.join(Z(),".local","share","launchpad","logs","rabbitmq.log"),port:5672,dependencies:[],healthCheck:{command:["rabbitmqctl","status"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},elasticsearch:{name:"elasticsearch",displayName:"Elasticsearch",description:"Elasticsearch search engine",packageDomain:"elastic.co",executable:"elasticsearch",args:[],env:{ES_PATH_DATA:$.join(Z(),".local","share","launchpad","services","elasticsearch","data"),ES_PATH_LOGS:$.join(Z(),".local","share","launchpad","logs")},dataDirectory:$.join(Z(),".local","share","launchpad","services","elasticsearch","data"),logFile:$.join(Z(),".local","share","launchpad","logs","elasticsearch.log"),port:9200,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:9200/_health"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},caddy:{name:"caddy",displayName:"Caddy",description:"Caddy web server with automatic HTTPS",packageDomain:"caddyserver.com",executable:"caddy",args:["run","--config","{configFile}"],env:{},configFile:$.join(Z(),".local","share","launchpad","services","config","Caddyfile"),logFile:$.join(Z(),".local","share","launchpad","logs","caddy.log"),port:2015,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:2015/health"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},kafka:{name:"kafka",displayName:"Apache Kafka",description:"Distributed event streaming platform",packageDomain:"kafka.apache.org",executable:"kafka-server-start.sh",args:["{configFile}"],env:{KAFKA_HEAP_OPTS:"-Xmx1G -Xms1G",LOG_DIR:$.join(Z(),".local","share","launchpad","logs")},dataDirectory:$.join(Z(),".local","share","launchpad","services","kafka","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","kafka-server.properties"),logFile:$.join(Z(),".local","share","launchpad","logs","kafka.log"),port:9092,dependencies:[],healthCheck:{command:["kafka-broker-api-versions.sh","--bootstrap-server","localhost:9092"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},vault:{name:"vault",displayName:"HashiCorp Vault",description:"Secrets management, encryption as a service, and privileged access management",packageDomain:"vaultproject.io",executable:"vault",args:["server","-config","{configFile}"],env:{VAULT_API_ADDR:"http://localhost:8200",VAULT_ADDR:"http://localhost:8200"},dataDirectory:$.join(Z(),".local","share","launchpad","services","vault","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","vault.hcl"),logFile:$.join(Z(),".local","share","launchpad","logs","vault.log"),port:8200,dependencies:[],healthCheck:{command:["vault","status"],expectedExitCode:2,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},minio:{name:"minio",displayName:"MinIO",description:"High-performance, S3 compatible object storage",packageDomain:"min.io",executable:"minio",args:["server","{dataDir}","--address","localhost:9000","--console-address","localhost:9001"],env:{MINIO_ROOT_USER:"minioadmin",MINIO_ROOT_PASSWORD:"minioadmin"},dataDirectory:$.join(Z(),".local","share","launchpad","services","minio","data"),logFile:$.join(Z(),".local","share","launchpad","logs","minio.log"),port:9000,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:9000/minio/health/live"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},prometheus:{name:"prometheus",displayName:"Prometheus",description:"Monitoring system and time series database",packageDomain:"prometheus.io",executable:"prometheus",args:["--config.file={configFile}","--storage.tsdb.path={dataDir}","--web.console.libraries=/usr/share/prometheus/console_libraries","--web.console.templates=/usr/share/prometheus/consoles"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","prometheus","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","prometheus.yml"),logFile:$.join(Z(),".local","share","launchpad","logs","prometheus.log"),port:9090,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:9090/-/healthy"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},grafana:{name:"grafana",displayName:"Grafana",description:"Analytics and interactive visualization web application",packageDomain:"grafana.com",executable:"grafana-server",args:["--config={configFile}","--homepath={dataDir}"],env:{GF_PATHS_DATA:$.join(Z(),".local","share","launchpad","services","grafana","data"),GF_PATHS_LOGS:$.join(Z(),".local","share","launchpad","logs")},dataDirectory:$.join(Z(),".local","share","launchpad","services","grafana","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","grafana.ini"),logFile:$.join(Z(),".local","share","launchpad","logs","grafana.log"),port:3000,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:3000/api/health"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},jaeger:{name:"jaeger",displayName:"Jaeger",description:"Distributed tracing platform",packageDomain:"jaegertracing.io",executable:"jaeger-all-in-one",args:["--memory.max-traces","10000"],env:{},logFile:$.join(Z(),".local","share","launchpad","logs","jaeger.log"),port:16686,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:14269/"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},sonarqube:{name:"sonarqube",displayName:"SonarQube",description:"Continuous code quality and security analysis",packageDomain:"sonarqube.org",executable:"sonar.sh",args:["start"],env:{SONAR_JAVA_PATH:"java"},dataDirectory:$.join(Z(),".local","share","launchpad","services","sonarqube","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","sonar.properties"),logFile:$.join(Z(),".local","share","launchpad","logs","sonarqube.log"),port:9001,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:9000/api/system/status"],expectedExitCode:0,timeout:30,interval:60,retries:5},supportsGracefulShutdown:!0},consul:{name:"consul",displayName:"HashiCorp Consul",description:"Service networking platform for service discovery and configuration",packageDomain:"consul.io",executable:"consul",args:["agent","-dev","-config-dir","{configDir}","-data-dir","{dataDir}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","consul","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","consul.json"),logFile:$.join(Z(),".local","share","launchpad","logs","consul.log"),port:8500,dependencies:[],healthCheck:{command:["consul","members"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},etcd:{name:"etcd",displayName:"etcd",description:"Distributed reliable key-value store",packageDomain:"etcd.io",executable:"etcd",args:["--data-dir","{dataDir}","--listen-client-urls","http://localhost:2379","--advertise-client-urls","http://localhost:2379"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","etcd","data"),logFile:$.join(Z(),".local","share","launchpad","logs","etcd.log"),port:2379,dependencies:[],healthCheck:{command:["etcdctl","endpoint","health"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},influxdb:{name:"influxdb",displayName:"InfluxDB",description:"Time series database",packageDomain:"influxdata.com",executable:"influxd",args:["--config","{configFile}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","influxdb","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","influxdb.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","influxdb.log"),port:8086,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8086/ping"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},temporal:{name:"temporal",displayName:"Temporal",description:"Workflow orchestration platform",packageDomain:"temporal.io",executable:"temporal",args:["server","start-dev","--db-filename","{dataDir}/temporal.db"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","temporal","data"),logFile:$.join(Z(),".local","share","launchpad","logs","temporal.log"),port:7233,dependencies:[],healthCheck:{command:["temporal","operator","cluster","health"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},cockroachdb:{name:"cockroachdb",displayName:"CockroachDB",description:"Distributed SQL database",packageDomain:"cockroachlabs.com",executable:"cockroach",args:["start-single-node","--insecure","--store={dataDir}","--listen-addr=localhost:26257","--http-addr=localhost:8080"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","cockroachdb","data"),logFile:$.join(Z(),".local","share","launchpad","logs","cockroachdb.log"),port:26257,dependencies:[],healthCheck:{command:["cockroach","sql","--insecure","--execute=SELECT 1;"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},neo4j:{name:"neo4j",displayName:"Neo4j",description:"Graph database",packageDomain:"neo4j.com",executable:"neo4j",args:["console"],env:{NEO4J_HOME:$.join(Z(),".local","share","launchpad","services","neo4j"),NEO4J_DATA:$.join(Z(),".local","share","launchpad","services","neo4j","data"),NEO4J_LOGS:$.join(Z(),".local","share","launchpad","logs")},dataDirectory:$.join(Z(),".local","share","launchpad","services","neo4j","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","neo4j.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","neo4j.log"),port:7474,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:7474/db/data/"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},pulsar:{name:"pulsar",displayName:"Apache Pulsar",description:"Cloud-native distributed messaging and streaming platform",packageDomain:"pulsar.apache.org",executable:"pulsar",args:["standalone"],env:{PULSAR_MEM:"-Xms512m -Xmx512m -XX:MaxDirectMemorySize=256m",PULSAR_GC:"-XX:+UseG1GC"},dataDirectory:$.join(Z(),".local","share","launchpad","services","pulsar","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","standalone.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","pulsar.log"),port:6650,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8080/admin/v2/clusters"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},nats:{name:"nats",displayName:"NATS",description:"High-performance messaging system",packageDomain:"nats.io",executable:"nats-server",args:["--config","{configFile}"],env:{},configFile:$.join(Z(),".local","share","launchpad","services","config","nats.conf"),logFile:$.join(Z(),".local","share","launchpad","logs","nats.log"),port:4222,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8222/varz"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},jenkins:{name:"jenkins",displayName:"Jenkins",description:"Automation server for CI/CD",packageDomain:"jenkins.io",executable:"jenkins",args:["--httpPort=8090","--webroot={dataDir}/war"],env:{JENKINS_HOME:$.join(Z(),".local","share","launchpad","services","jenkins"),JAVA_OPTS:"-Xmx512m"},dataDirectory:$.join(Z(),".local","share","launchpad","services","jenkins"),logFile:$.join(Z(),".local","share","launchpad","logs","jenkins.log"),port:8090,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8090/login"],expectedExitCode:0,timeout:30,interval:60,retries:5},supportsGracefulShutdown:!0},localstack:{name:"localstack",displayName:"LocalStack",description:"Local AWS cloud stack for development",packageDomain:"localstack.cloud",executable:"localstack",args:["start"],env:{LOCALSTACK_HOST:"localhost:4566",DATA_DIR:$.join(Z(),".local","share","launchpad","services","localstack","data"),TMPDIR:$.join(Z(),".local","share","launchpad","services","localstack","tmp")},dataDirectory:$.join(Z(),".local","share","launchpad","services","localstack","data"),logFile:$.join(Z(),".local","share","launchpad","logs","localstack.log"),port:4566,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:4566/_localstack/health"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},hasura:{name:"hasura",displayName:"Hasura",description:"GraphQL API with real-time subscriptions",packageDomain:"hasura.io",executable:"graphql-engine",args:["serve"],env:{HASURA_GRAPHQL_DATABASE_URL:"postgres://localhost:5432/postgres",HASURA_GRAPHQL_ENABLE_CONSOLE:"true",HASURA_GRAPHQL_DEV_MODE:"true",HASURA_GRAPHQL_ENABLED_LOG_TYPES:"startup, http-log, webhook-log, websocket-log, query-log",HASURA_GRAPHQL_SERVER_PORT:"8085"},logFile:$.join(Z(),".local","share","launchpad","logs","hasura.log"),port:8085,dependencies:["postgres"],healthCheck:{command:["curl","-f","-s","http://localhost:8085/healthz"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},keycloak:{name:"keycloak",displayName:"Keycloak",description:"Identity and access management",packageDomain:"keycloak.org",executable:"kc.sh",args:["start-dev","--http-port=8088"],env:{KEYCLOAK_ADMIN:"admin",KEYCLOAK_ADMIN_PASSWORD:"admin",KC_DB:"dev-file",KC_DB_URL_DATABASE:$.join(Z(),".local","share","launchpad","services","keycloak","data","keycloak.db")},dataDirectory:$.join(Z(),".local","share","launchpad","services","keycloak","data"),logFile:$.join(Z(),".local","share","launchpad","logs","keycloak.log"),port:8088,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8088/health"],expectedExitCode:0,timeout:30,interval:60,retries:5},supportsGracefulShutdown:!0},clickhouse:{name:"clickhouse",displayName:"ClickHouse",description:"Columnar database for analytics",packageDomain:"clickhouse.com",executable:"clickhouse-server",args:["--config-file={configFile}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","clickhouse","data"),configFile:$.join(Z(),".local","share","launchpad","services","config","clickhouse-config.xml"),logFile:$.join(Z(),".local","share","launchpad","logs","clickhouse.log"),port:8123,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:8123/ping"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0},verdaccio:{name:"verdaccio",displayName:"Verdaccio",description:"Private npm registry",packageDomain:"verdaccio.org",executable:"verdaccio",args:["--config","{configFile}"],env:{},dataDirectory:$.join(Z(),".local","share","launchpad","services","verdaccio","storage"),configFile:$.join(Z(),".local","share","launchpad","services","config","verdaccio.yaml"),logFile:$.join(Z(),".local","share","launchpad","logs","verdaccio.log"),port:4873,dependencies:[],healthCheck:{command:["curl","-f","-s","http://localhost:4873/-/ping"],expectedExitCode:0,timeout:5,interval:30,retries:3},supportsGracefulShutdown:!0},meilisearch:{name:"meilisearch",displayName:"Meilisearch",description:"Meilisearch search engine",packageDomain:"meilisearch.com",executable:"meilisearch",args:["--http-addr","127.0.0.1:{port}","--db-path","{dataDir}","--master-key","{masterKey}"],env:{MEILI_HTTP_ADDR:"127.0.0.1:{port}",MEILI_DB_PATH:"{dataDir}",MEILI_MASTER_KEY:"{masterKey}",MEILI_ENV:"development"},dataDirectory:$.join(Z(),".local","share","launchpad","services","meilisearch","data"),logFile:$.join(Z(),".local","share","launchpad","logs","meilisearch.log"),port:7700,dependencies:[],healthCheck:{command:["curl","-f","-s","http://127.0.0.1:7700/health"],expectedExitCode:0,timeout:10,interval:30,retries:3},supportsGracefulShutdown:!0,config:{masterKey:"launchpad-dev-key-12345678901234567890123456789012",httpAddr:"127.0.0.1:7700",environment:"development",maxIndexSize:"100 MB",maxTaskDbSize:"100 MB",httpPayloadSizeLimit:"100 MB",logLevel:"INFO",maxIndexingMemory:"2 GB",maxIndexingThreads:4}}};function t(Q){return p[Q.toLowerCase()]}function DG(){return Object.values(p)}function $G(Q){return Object.values(p).filter((W)=>W.packageDomain===Q)}function SG(Q){return Q.toLowerCase()in p}function uG(Q){let W=[];for(let G of Q){let Y=$G(G);W.push(...Y)}return W}function o(Q){switch(Q.toLowerCase()){case"redis":return`# Redis configuration file
port 6379
bind 127.0.0.1
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir ${$.join(Z(),".local","share","launchpad","services","redis","data")}
logfile ${$.join(Z(),".local","share","launchpad","logs","redis.log")}
loglevel notice
`;case"nginx":return`# Nginx configuration file
worker_processes auto;
error_log ${$.join(Z(),".local","share","launchpad","logs","nginx-error.log")};
pid ${$.join(Z(),".local","share","launchpad","services","nginx","nginx.pid")};
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log ${$.join(Z(),".local","share","launchpad","logs","nginx-access.log")};
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
location / {
root ${$.join(Z(),".local","share","launchpad","services","nginx","html")};
index index.html index.htm;
}
location /health {
access_log off;
return 200 "healthy\\n";
add_header Content-Type text/plain;
}
}
}
`;case"caddy":return`# Caddyfile
:2015 {
respond /health "healthy"
file_server browse
root * ${$.join(Z(),".local","share","launchpad","services","caddy","html")}
}
`;case"kafka":return`# Kafka Server Properties
broker.id=0
listeners=PLAINTEXT://localhost:9092
advertised.listeners=PLAINTEXT://localhost:9092
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=${$.join(Z(),".local","share","launchpad","services","kafka","data")}
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=localhost:2181
zookeeper.connection.timeout.ms=18000
group.initial.rebalance.delay.ms=0
`;case"vault":return`# Vault Configuration
storage "file" {
path = "${$.join(Z(),".local","share","launchpad","services","vault","data")}"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
api_addr = "http://127.0.0.1:8200"
cluster_addr = "https://127.0.0.1:8201"
ui = true
disable_mlock = true
`;case"prometheus":return`# Prometheus Configuration
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
`;case"grafana":return`# Grafana Configuration
[server]
http_addr = 127.0.0.1
http_port = 3000
domain = localhost
[database]
type = sqlite3
path = ${$.join(Z(),".local","share","launchpad","services","grafana","data","grafana.db")}
[session]
provider = file
provider_config = ${$.join(Z(),".local","share","launchpad","services","grafana","data","sessions")}
[analytics]
reporting_enabled = false
check_for_updates = false
[security]
admin_user = admin
admin_password = admin
[users]
allow_sign_up = false
allow_org_create = false
auto_assign_org = true
auto_assign_org_role = Viewer
[log]
mode = file
level = info
`;case"consul":return`{
"datacenter": "dc1",
"data_dir": "${$.join(Z(),".local","share","launchpad","services","consul","data")}",
"log_level": "INFO",
"server": true,
"bootstrap_expect": 1,
"bind_addr": "127.0.0.1",
"client_addr": "127.0.0.1",
"retry_join": ["127.0.0.1"],
"ui_config": {
"enabled": true
},
"connect": {
"enabled": true
},
"ports": {
"grpc": 8502
}
}
`;case"influxdb":return`# InfluxDB Configuration
[meta]
dir = "${$.join(Z(),".local","share","launchpad","services","influxdb","data","meta")}"
[data]
dir = "${$.join(Z(),".local","share","launchpad","services","influxdb","data","data")}"
wal-dir = "${$.join(Z(),".local","share","launchpad","services","influxdb","data","wal")}"
[coordinator]
[retention]
[shard-precreation]
[monitor]
[http]
enabled = true
bind-address = ":8086"
auth-enabled = false
log-enabled = true
write-tracing = false
pprof-enabled = true
https-enabled = false
[logging]
format = "auto"
level = "info"
`;case"neo4j":return`# Neo4j Configuration
dbms.default_database=neo4j
dbms.directories.data=${$.join(Z(),".local","share","launchpad","services","neo4j","data")}
dbms.directories.logs=${$.join(Z(),".local","share","launchpad","logs")}
# Network settings
dbms.default_listen_address=0.0.0.0
dbms.connector.bolt.enabled=true
dbms.connector.bolt.listen_address=:7687
dbms.connector.http.enabled=true
dbms.connector.http.listen_address=:7474
# Security settings (development mode)
dbms.security.auth_enabled=false
# Memory settings
dbms.memory.heap.initial_size=512m
dbms.memory.heap.max_size=512m
`;case"nats":return`# NATS Server Configuration
port: 4222
monitor_port: 8222
# Logging
debug: false
trace: false
logtime: true
# Security
authorization {
default_permissions: {
publish: ">"
subscribe: ">"
}
}
# JetStream (optional)
jetstream: {
store_dir: "${$.join(Z(),".local","share","launchpad","services","nats","data")}"
max_memory_store: 256MB
max_file_store: 2GB
}
`;case"clickhouse":return`<?xml version="1.0"?>
<clickhouse>
<logger>
<level>information</level>
<log>${$.join(Z(),".local","share","launchpad","logs","clickhouse.log")}</log>
<errorlog>${$.join(Z(),".local","share","launchpad","logs","clickhouse-error.log")}</errorlog>
<size>1000M</size>
<count>10</count>
</logger>
<http_port>8123</http_port>
<tcp_port>9000</tcp_port>
<path>${$.join(Z(),".local","share","launchpad","services","clickhouse","data")}/</path>
<tmp_path>${$.join(Z(),".local","share","launchpad","services","clickhouse","tmp")}/</tmp_path>
<user_files_path>${$.join(Z(),".local","share","launchpad","services","clickhouse","user_files")}/</user_files_path>
<users_config>users.xml</users_config>
<default_profile>default</default_profile>
<default_database>default</default_database>
<timezone>UTC</timezone>
<listen_host>::</listen_host>
<listen_host>0.0.0.0</listen_host>
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<use_uncompressed_cache>0</use_uncompressed_cache>
<load_balancing>random</load_balancing>
</default>
</profiles>
<users>
<default>
<password></password>
<networks incl="networks" replace="replace">
<ip>::/0</ip>
</networks>
<profile>default</profile>
<quota>default</quota>
</default>
</users>
<quotas>
<default>
<interval>
<duration>3600</duration>
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
</quotas>
</clickhouse>
`;case"verdaccio":return`# Verdaccio Configuration
storage: ${$.join(Z(),".local","share","launchpad","services","verdaccio","storage")}
auth:
htpasswd:
file: ./htpasswd
max_users: 1000
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
'@*/*':
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
'**':
access: $all
publish: $authenticated
unpublish: $authenticated
proxy: npmjs
server:
keepAliveTimeout: 60
middlewares:
audit:
enabled: true
logs: { type: stdout, format: pretty, level: http }
listen: 0.0.0.0:4873
`;case"php":return`; PHP Configuration File (php.ini)
; This file is automatically generated by Launchpad
[PHP]
; Engine Settings
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
; Resource Limits
max_execution_time = 300
max_input_time = 60
memory_limit = 512M
; Error handling and logging
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = On
html_errors = On
error_log = ${$.join(Z(),".local","share","launchpad","logs","php-error.log")}
; File Uploads
file_uploads = On
upload_tmp_dir = ${$.join(Z(),".local","share","launchpad","services","php","tmp")}
upload_max_filesize = 64M
max_file_uploads = 20
; Post Settings
post_max_size = 64M
; Extensions
extension=pdo
extension=pdo_sqlite
extension=sqlite3
extension=pdo_mysql
extension=mysqli
extension=pdo_pgsql
extension=pgsql
extension=openssl
extension=json
extension=mbstring
extension=curl
extension=zip
extension=gd
extension=intl
extension=fileinfo
extension=tokenizer
extension=xml
extension=xmlreader
extension=xmlwriter
extension=simplexml
extension=dom
; Sessions
session.save_handler = files
session.save_path = "${$.join(Z(),".local","share","launchpad","services","php","sessions")}"
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
; Timezone
date.timezone = UTC
`;default:return null}}import w from"fs";import{homedir as g,platform as d}from"os";import B from"path";import m from"process";function a(Q){let{definition:W}=Q;if(!W)throw new Error(`Service definition not found for ${Q.name}`);let G=H.services;if(!G)throw new Error("Services configuration not found");let Y=Q.logFile?B.dirname(Q.logFile):G.logDir,K=Q.dataDir||W.dataDirectory,_=(W.args||[]).map((A)=>{let X=A.replace("{dataDir}",K||"").replace("{configFile}",Q.configFile||W.configFile||"").replace("{logFile}",Q.logFile||W.logFile||"").replace("{pidFile}",W.pidFile||"").replace("{port}",String(W.port||5432));if(Q.config)for(let[T,L]of Object.entries(Q.config))X=X.replace(new RegExp(`{${T}}`,"g"),String(L));return X}),z=S(W.executable)||W.executable,J={};try{let A=B.dirname(z),X=B.dirname(A),T=B.dirname(X),L=B.dirname(T);if(w.existsSync(L)&&w.existsSync(B.join(L,"bin"))){let M=B.join(L,"bin"),j=B.join(L,"sbin"),I=m.env.PATH||"";J.PATH=[M,j,I].filter(Boolean).join(":");let x=[],C=(k)=>{try{if(w.existsSync(k)&&!x.includes(k))x.push(k)}catch{}};C(B.join(L,"lib")),C(B.join(L,"lib64"));try{let k=w.readdirSync(L,{withFileTypes:!0});for(let D of k){if(!D.isDirectory())continue;if(["bin","sbin","share","include","etc","pkgs"].includes(D.name))continue;let P=B.join(L,D.name),ZG=w.readdirSync(P,{withFileTypes:!0}).filter((l)=>l.isDirectory()&&l.name.startsWith("v"));for(let l of ZG)C(B.join(P,l.name,"lib")),C(B.join(P,l.name,"lib64"))}}catch{}if(x.length>0){let k=m.env.DYLD_LIBRARY_PATH||"";J.DYLD_LIBRARY_PATH=[x.join(":"),k].filter(Boolean).join(":");let D=m.env.DYLD_FALLBACK_LIBRARY_PATH||"";J.DYLD_FALLBACK_LIBRARY_PATH=[x.join(":"),D].filter(Boolean).join(":")}}}catch{}return{Label:`com.launchpad.${W.name||Q.name}`,ProgramArguments:[z,..._],WorkingDirectory:W.workingDirectory||K||"",EnvironmentVariables:{...Object.fromEntries(Object.entries(W.env||{}).map(([A,X])=>{let T=String(X).replace("{dataDir}",K||"").replace("{configFile}",Q.configFile||W.configFile||"").replace("{logFile}",Q.logFile||W.logFile||"").replace("{pidFile}",W.pidFile||"").replace("{port}",String(W.port||5432));if(Q.config)for(let[L,V]of Object.entries(Q.config))T=T.replace(new RegExp(`{${L}}`,"g"),String(V));return[A,T]})),...Object.fromEntries(Object.entries(Q.config||{}).map(([A,X])=>[A,String(X)])),...J},StandardOutPath:Q.logFile||B.join(Y||"",`${W.name||Q.name}.log`),StandardErrorPath:Q.logFile||B.join(Y||"",`${W.name||Q.name}.log`),RunAtLoad:Q.enabled||!1,KeepAlive:{SuccessfulExit:!1},UserName:m.env.USER||"root"}}function r(Q){let{definition:W}=Q;if(!W)throw new Error(`Service definition not found for ${Q.name}`);let G=H.services;if(!G)throw new Error("Services configuration not found");let Y=Q.logFile?B.dirname(Q.logFile):G.logDir,K=Q.dataDir||W.dataDirectory,_=(W.args||[]).map((A)=>{let X=A.replace("{dataDir}",K||"").replace("{configFile}",Q.configFile||W.configFile||"").replace("{logFile}",Q.logFile||W.logFile||"").replace("{pidFile}",W.pidFile||"").replace("{port}",String(W.port||5432));if(Q.config)for(let[T,L]of Object.entries(Q.config))X=X.replace(new RegExp(`{${T}}`,"g"),String(L));return X}),z=S(W.executable)||W.executable,J=Object.entries({...Object.fromEntries(Object.entries(W.env||{}).map(([A,X])=>{let T=String(X).replace("{dataDir}",K||"").replace("{configFile}",Q.configFile||W.configFile||"").replace("{logFile}",Q.logFile||W.logFile||"").replace("{pidFile}",W.pidFile||"").replace("{port}",String(W.port||5432));if(Q.config)for(let[L,V]of Object.entries(Q.config))T=T.replace(new RegExp(`{${L}}`,"g"),String(V));return[A,T]})),...Object.fromEntries(Object.entries(Q.config||{}).map(([A,X])=>[A,String(X)]))}).map(([A,X])=>`${A}=${X}`);return{Unit:{Description:`${W.displayName||Q.name} - ${W.description||""}`,After:["network.target",...(W.dependencies||[]).map((A)=>`launchpad-${A}.service`)],Wants:(W.dependencies||[]).map((A)=>`launchpad-${A}.service`)},Service:{Type:"simple",ExecStart:`${z} ${_.join(" ")}`,ExecStop:W.supportsGracefulShutdown?`${S("pkill")||"pkill"} -TERM -f ${W.executable}`:void 0,WorkingDirectory:W.workingDirectory||K,Environment:J.length>0?J:void 0,User:m.env.USER||"root",Restart:G.autoRestart?"on-failure":"no",RestartSec:5,TimeoutStartSec:G.startupTimeout,TimeoutStopSec:G.shutdownTimeout,PIDFile:W.pidFile},Install:{WantedBy:["multi-user.target"]}}}async function i(Q,W){let G=B.join(g(),"Library","LaunchAgents");await w.promises.mkdir(G,{recursive:!0});let Y=B.join(G,`${W.Label}.plist`),K=KG(W);if(await w.promises.writeFile(Y,K,"utf8"),H.verbose)console.log(`\u2705 Created launchd plist: ${Y}`);return Y}async function e(Q,W){let G=B.join(g(),".config","systemd","user");await w.promises.mkdir(G,{recursive:!0});let Y=B.join(G,`launchpad-${Q.definition?.name||Q.name}.service`),K=zG(W);if(await w.promises.writeFile(Y,K,"utf8"),H.verbose)console.log(`\u2705 Created systemd service: ${Y}`);return Y}async function pG(Q){let W=d();if(W==="darwin"){let G=B.join(g(),"Library","LaunchAgents",`com.launchpad.${Q}.plist`);if(w.existsSync(G)){if(await w.promises.unlink(G),H.verbose)console.warn(`\uD83D\uDDD1\uFE0F Removed launchd plist: ${G}`)}}else if(W==="linux"){let G=B.join(g(),".config","systemd","user",`launchpad-${Q}.service`);if(w.existsSync(G)){if(await w.promises.unlink(G),H.verbose)console.warn(`\uD83D\uDDD1\uFE0F Removed systemd service: ${G}`)}}}function n(Q){let W=d();if(W==="darwin")return B.join(g(),"Library","LaunchAgents",`com.launchpad.${Q}.plist`);else if(W==="linux")return B.join(g(),".config","systemd","user",`launchpad-${Q}.service`);return null}function h(){let Q=d();return Q==="darwin"||Q==="linux"}function dG(){let Q=d();if(Q==="darwin")return"launchd";else if(Q==="linux")return"systemd";return"unknown"}function KG(Q){let W=[];W.push('<?xml version="1.0" encoding="UTF-8"?>'),W.push('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'),W.push('<plist version="1.0">'),W.push("<dict>");let G=(Y,K,_=1)=>{let z=" ".repeat(_);if(W.push(`${z}<key>${Y}</key>`),typeof K==="string")W.push(`${z}<string>${s(K)}</string>`);else if(typeof K==="boolean")W.push(`${z}<${K?"true":"false"}/>`);else if(typeof K==="number")W.push(`${z}<integer>${K}</integer>`);else if(Array.isArray(K))W.push(`${z}<array>`),K.forEach((J)=>{if(typeof J==="string")W.push(`${z} <string>${s(J)}</string>`)}),W.push(`${z}</array>`);else if(typeof K==="object"&&K!==null)W.push(`${z}<dict>`),Object.entries(K).forEach(([J,A])=>{G(J,A,_+1)}),W.push(`${z}</dict>`)};return Object.entries(Q).forEach(([Y,K])=>{if(K!==void 0)G(Y,K)}),W.push("</dict>"),W.push("</plist>"),W.join(`
`)}function zG(Q){let W=[],G=(Y,K)=>{W.push(`[${Y}]`),Object.entries(K).forEach(([_,z])=>{if(z!==void 0)if(Array.isArray(z))z.forEach((J)=>{W.push(`${_}=${J}`)});else W.push(`${_}=${z}`)}),W.push("")};if(G("Unit",Q.Unit),G("Service",Q.Service),Q.Install)G("Install",Q.Install);return W.join(`
`)}function s(Q){return Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var f=null;async function JG(){if(f)return f;return f={services:new Map,operations:[],config:H.services,lastScanTime:new Date},await AG(),f}async function N(){if(!f)return await JG();return f}async function AG(){let Q=H.services;if(!Q)throw new Error("Services configuration not found");let W=[Q.dataDir,Q.logDir,Q.configDir].filter(Boolean);for(let G of W)await O.promises.mkdir(G,{recursive:!0})}async function XG(Q){if(!h())throw new Error(`Service management is not supported on ${b()}`);let W=await N(),G={action:"start",serviceName:Q,timestamp:new Date,status:"pending"};if(U.env.NODE_ENV==="test"||U.env.LAUNCHPAD_TEST_MODE==="true")try{let Y=await v(Q);return console.warn(`\uD83E\uDDEA Test mode: Mocking start of service ${Q}`),G.result="success",G.duration=0,W.operations.push(G),Y.status="running",Y.lastCheckedAt=new Date,!0}catch(Y){return console.warn(`\uD83E\uDDEA Test mode: Failed to start unknown service ${Q}`),G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=0,W.operations.push(G),!1}try{let Y=await v(Q);if(Y.status==="running"){let J=await u(Y);if(!J)await new Promise((A)=>setTimeout(A,500)),J=await u(Y);if(J)return y(`\u2705 Service ${Q} is already running`,!0),G.result="success",G.duration=0,W.operations.push(G),!0;else y(`\u26A0\uFE0F ${Y.definition?.displayName||Q} reported running but appears unhealthy. Attempting gentle restart...`,!0),await QG(Q)}if(y(`\uD83D\uDE80 Starting ${Y.definition?.displayName||Q}...`,!0),Y.status="starting",Y.lastCheckedAt=new Date,Y.startedAt=new Date,!await BG(Y))return console.error(`\u274C Failed to install ${Y.definition?.displayName||Q} package`),G.result="failure",G.error="Package installation failed",W.operations.push(G),!1;if(Y.definition?.name==="php"){if(!await VG(Y)&&H.verbose)console.warn("\u26A0\uFE0F Some PHP database extensions may not be available; not attempting PECL. Proceeding.")}if(!await RG(Y))return console.error(`\u274C Failed to auto-initialize ${Y.definition?.displayName||Q}`),G.result="failure",G.error="Auto-initialization failed",W.operations.push(G),!1;if(Y.definition?.initCommand&&!await TG(Y))console.warn(`\uD83D\uDD27 Initializing ${Y.definition?.displayName||Q}...`),await UG(Y);if(await c(Y),Y.definition?.name==="postgres"){let J=WG();Y.config={...Y.config||{},projectDatabase:J.replace(/\W/g,"_"),appUser:"postgres",appPassword:""}}let z=await _G(Y);if(!z&&Y.definition?.name==="postgres")try{let{findBinaryInPath:J}=await import("./chunk-wkk6vc0r.js"),A=J("pg_ctl")||"pg_ctl",X=Y.dataDir||Y.definition.dataDirectory,L=`-p ${Y.definition.port||5432} -c listen_addresses=127.0.0.1`;console.warn("\u26A0\uFE0F launchd/system start failed; falling back to pg_ctl start"),await new Promise((V,M)=>{let j=E(A,["-D",String(X),"-o",L,"-w","start"],{stdio:H.verbose?"inherit":"pipe"});j.on("close",(I)=>{if(I===0)V();else M(new Error(`pg_ctl start failed with exit ${I}`))}),j.on("error",M)}),z=!0}catch(J){console.error(`\u274C Fallback start failed: ${J instanceof Error?J.message:String(J)}`)}if(!z)return console.error(`\u274C Failed to start ${Y.definition?.displayName||Q}`),G.result="failure",G.error="Start failed",W.operations.push(G),!1;if(Y.definition?.name==="postgres"){let J=await u(Y);if(!J)await new Promise((A)=>setTimeout(A,500)),J=await u(Y);if(!J)try{let{findBinaryInPath:A}=await import("./chunk-wkk6vc0r.js"),X=A("pg_ctl")||"pg_ctl",T=Y.dataDir||Y.definition.dataDirectory,V=`-p ${Y.definition.port||5432} -c listen_addresses=127.0.0.1`;console.warn("\u26A0\uFE0F Service unhealthy after start; attempting pg_ctl restart");let M=E(X,["-D",String(T),"-m","fast","stop"],{stdio:"ignore"});await new Promise((j)=>M.on("close",()=>j(null))),await new Promise((j,I)=>{let x=E(X,["-D",String(T),"-o",V,"-w","start"],{stdio:H.verbose?"inherit":"pipe"});x.on("close",(C)=>C===0?j():I(new Error(`pg_ctl start failed with exit ${C}`))),x.on("error",I)})}catch(A){console.error(`\u274C pg_ctl restart failed: ${A instanceof Error?A.message:String(A)}`)}}if(await new Promise((J)=>setTimeout(J,500)),await jG(Y),Y.definition?.name==="postgres"&&U.platform==="darwin")try{await new Promise((J)=>setTimeout(J,300))}catch{}return setTimeout(()=>{u(Y)},2000),G.result="success",G.duration=0,W.operations.push(G),!0}catch(Y){return console.error(`\u274C Failed to start service ${Q}: ${Y instanceof Error?Y.message:String(Y)}`),G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=0,W.operations.push(G),!1}}async function QG(Q){if(!h())throw new Error(`Service management is not supported on ${b()}`);let W=await N(),G={action:"stop",serviceName:Q,timestamp:new Date,status:"pending"};if(U.env.NODE_ENV==="test"||U.env.LAUNCHPAD_TEST_MODE==="true"){let Y=W.services.get(Q);if(!Y)return console.warn(`\uD83E\uDDEA Test mode: Service ${Q} is not registered`),G.result="success",G.duration=0,W.operations.push(G),!0;return console.warn(`\uD83E\uDDEA Test mode: Mocking stop of service ${Q}`),G.result="success",G.duration=0,W.operations.push(G),Y.status="stopped",Y.lastCheckedAt=new Date,!0}try{let Y=W.services.get(Q);if(!Y)return console.warn(`\u26A0\uFE0F Service ${Q} is not registered`),G.result="success",G.duration=0,W.operations.push(G),!0;if(Y.status==="stopped")return console.log(`\u2705 Service ${Q} is already stopped`),G.result="success",G.duration=0,W.operations.push(G),!0;console.warn(`\uD83D\uDED1 Stopping ${Y.definition?.displayName||Q}...`),Y.status="stopping",Y.lastCheckedAt=new Date;let K=await HG(Y);if(K)Y.status="stopped",Y.pid=void 0,Y.startedAt=void 0,console.log(`\u2705 ${Y.definition?.displayName||Q} stopped successfully`),G.result="success";else Y.status="failed",G.result="failure",G.error="Failed to stop service";return G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),K}catch(Y){return G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),console.error(`\u274C Failed to stop ${Q}: ${G.error}`),!1}}async function QQ(Q){if(console.warn(`\uD83D\uDD04 Restarting ${Q}...`),!await QG(Q))return!1;return await new Promise((G)=>setTimeout(G,1000)),await XG(Q)}async function WQ(Q){if(!h())throw new Error(`Service management is not supported on ${b()}`);let W=await N(),G={action:"enable",serviceName:Q,timestamp:new Date,status:"pending"};if(U.env.NODE_ENV==="test"||U.env.LAUNCHPAD_TEST_MODE==="true")try{let Y=await v(Q);return console.warn(`\uD83E\uDDEA Test mode: Mocking enable of service ${Q}`),G.result="success",G.duration=0,W.operations.push(G),Y.enabled=!0,!0}catch(Y){return console.warn(`\uD83E\uDDEA Test mode: Failed to enable unknown service ${Q}`),G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=0,W.operations.push(G),!1}try{let Y=await v(Q);if(Y.enabled)return console.log(`\u2705 Service ${Q} is already enabled`),G.result="success",G.duration=0,W.operations.push(G),!0;console.warn(`\uD83D\uDD27 Enabling ${Y.definition?.displayName||Q} for auto-start...`),Y.enabled=!0,await c(Y);let K=await LG(Y);if(K)console.log(`\u2705 ${Y.definition?.displayName||Q} enabled for auto-start`),G.result="success";else Y.enabled=!1,G.result="failure",G.error="Failed to enable service";return G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),K}catch(Y){return G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),console.error(`\u274C Failed to enable ${Q}: ${G.error}`),!1}}async function YQ(Q){if(!h())throw new Error(`Service management is not supported on ${b()}`);let W=await N(),G={action:"disable",serviceName:Q,timestamp:new Date,status:"pending"};if(U.env.NODE_ENV==="test"||U.env.LAUNCHPAD_TEST_MODE==="true"){let Y=W.services.get(Q);if(!Y)return console.warn(`\uD83E\uDDEA Test mode: Service ${Q} is not registered`),G.result="success",G.duration=0,W.operations.push(G),!0;return console.warn(`\uD83E\uDDEA Test mode: Mocking disable of service ${Q}`),G.result="success",G.duration=0,W.operations.push(G),Y.enabled=!1,!0}try{let Y=W.services.get(Q);if(!Y)return console.warn(`\u26A0\uFE0F Service ${Q} is not registered`),G.result="success",G.duration=0,W.operations.push(G),!0;if(!Y.enabled)return console.log(`\u2705 Service ${Q} is already disabled`),G.result="success",G.duration=0,W.operations.push(G),!0;console.warn(`\uD83D\uDD27 Disabling ${Y.definition?.displayName||Q} from auto-start...`),Y.enabled=!1,await c(Y);let K=await OG(Y);if(K)console.log(`\u2705 ${Y.definition?.displayName||Q} disabled from auto-start`),G.result="success";else Y.enabled=!0,G.result="failure",G.error="Failed to disable service";return G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),K}catch(Y){return G.result="failure",G.error=Y instanceof Error?Y.message:String(Y),G.duration=Date.now()-G.timestamp.getTime(),W.operations.push(G),console.error(`\u274C Failed to disable ${Q}: ${G.error}`),!1}}async function ZQ(Q){let G=(await N()).services.get(Q);if(!G)return"stopped";if(G.status==="running"){if(!await u(G))G.status="stopped"}return G.status}async function $Q(){let Q=await N(),W=Array.from(Q.services.values());for(let G of W)await u(G);return W}async function v(Q){let W=await N(),G=W.services.get(Q);if(G)return G;let Y=t(Q);if(!Y)throw new Error(`Unknown service: ${Q}`);return G={name:Q,definition:Y,status:"stopped",lastCheckedAt:new Date,enabled:!1,config:{...Y.config}},W.services.set(Q,G),G}async function TG(Q){let{definition:W}=Q;if(W?.