@ebowwa/pkg-ops 0.1.16 → 0.1.18

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/bridge.d.ts CHANGED
@@ -71,6 +71,41 @@ export interface InstalledPackageInfo {
71
71
  version: string;
72
72
  distSizeBytes: number | null;
73
73
  installedAt: string | null;
74
+ /** Total number of installed versions */
75
+ totalVersions?: number;
76
+ /** All installed versions */
77
+ versions?: VersionInfo[];
78
+ }
79
+ /**
80
+ * Version information for a package.
81
+ */
82
+ export interface VersionInfo {
83
+ version: string;
84
+ installedAt: string;
85
+ distSizeBytes: number | null;
86
+ fileCount: number | null;
87
+ active: boolean;
88
+ }
89
+ /**
90
+ * Result of switching versions.
91
+ */
92
+ export interface SwitchResult {
93
+ success: boolean;
94
+ packageName: string;
95
+ fromVersion: string;
96
+ toVersion: string;
97
+ message: string;
98
+ }
99
+ /**
100
+ * Result of pruning old versions.
101
+ */
102
+ export interface PruneResult {
103
+ success: boolean;
104
+ packageName: string;
105
+ removedVersions: string[];
106
+ keptVersions: string[];
107
+ freedBytes: number;
108
+ message: string;
74
109
  }
75
110
  /**
76
111
  * Bridge to the Rust worker process.
@@ -130,6 +165,34 @@ export declare class RustBridge {
130
165
  * Get detailed installed package info.
131
166
  */
132
167
  getInstalledInfo(): Promise<InstalledPackageInfo[]>;
168
+ /**
169
+ * List all installed versions of a package.
170
+ */
171
+ listVersions(packageName: string): Promise<VersionInfo[]>;
172
+ /**
173
+ * Switch to a specific installed version.
174
+ */
175
+ switchVersion(packageName: string, version: string): Promise<SwitchResult>;
176
+ /**
177
+ * Remove old versions, keeping only the N most recent.
178
+ */
179
+ pruneVersions(packageName: string, keepCount: number): Promise<PruneResult>;
180
+ /**
181
+ * Remove a specific version.
182
+ */
183
+ removeVersion(packageName: string, version: string): Promise<{
184
+ success: boolean;
185
+ message: string;
186
+ }>;
187
+ /**
188
+ * Get packages with multiple versions installed.
189
+ */
190
+ getMultiVersionPackages(): Promise<Array<{
191
+ packageName: string;
192
+ activeVersion: string;
193
+ totalVersions: number;
194
+ versions: string[];
195
+ }>>;
133
196
  private getBinaryPath;
134
197
  private sendRequest;
135
198
  private processBuffer;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -14,9 +14,22 @@
14
14
  * await saveConfig(config);
15
15
  * ```
16
16
  */
17
+ /**
18
+ * Metadata for a single installed version.
19
+ */
20
+ export interface VersionMetadata {
21
+ /** ISO timestamp when this version was installed */
22
+ installedAt: string;
23
+ /** Size of the dist directory in bytes */
24
+ distSizeBytes: number | null;
25
+ /** Number of files in dist */
26
+ fileCount: number | null;
27
+ }
17
28
  export interface PackageConfig {
18
- /** Package version (semver or "latest") */
29
+ /** Currently active version (semver) */
19
30
  version: string;
31
+ /** All installed versions with metadata */
32
+ versions: Record<string, VersionMetadata>;
20
33
  /** Associated systemd service name (without .service suffix) */
21
34
  service?: string;
22
35
  /** Whether to auto-start the service after install */
@@ -89,4 +102,45 @@ export declare function parsePackageSpec(spec: string): {
89
102
  name: string;
90
103
  version: string;
91
104
  };
105
+ /**
106
+ * Get all installed versions for a package.
107
+ */
108
+ export declare function getInstalledVersions(packageName: string): VersionMetadata[];
109
+ /**
110
+ * Check if a specific version is installed.
111
+ */
112
+ export declare function isVersionInstalled(packageName: string, version: string): boolean;
113
+ /**
114
+ * Get the active version for a package.
115
+ */
116
+ export declare function getActiveVersion(packageName: string): string | null;
117
+ /**
118
+ * Add a new version to the package config.
119
+ */
120
+ export declare function addPackageVersion(packageName: string, version: string, metadata: Omit<VersionMetadata, "installedAt"> & {
121
+ installedAt?: string;
122
+ }): void;
123
+ /**
124
+ * Remove a version from the package config.
125
+ * Returns true if the version was removed, false if it didn't exist.
126
+ */
127
+ export declare function removePackageVersion(packageName: string, version: string): boolean;
128
+ /**
129
+ * Set the active version for a package.
130
+ * Returns true if successful, false if version not installed.
131
+ */
132
+ export declare function setActiveVersion(packageName: string, version: string): boolean;
133
+ /**
134
+ * Get the count of installed versions for a package.
135
+ */
136
+ export declare function getVersionCount(packageName: string): number;
137
+ /**
138
+ * Get packages with multiple versions installed.
139
+ */
140
+ export declare function getPackagesWithMultipleVersions(): Array<{
141
+ name: string;
142
+ activeVersion: string;
143
+ totalVersions: number;
144
+ versions: string[];
145
+ }>;
92
146
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAChD;AAMD,eAAO,MAAM,cAAc,EAAE,YAK5B,CAAC;AAEF,eAAO,MAAM,UAAU,iBAAiB,CAAC;AACzC,eAAO,MAAM,WAAW,6BAA8B,CAAC;AAMvD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAoBzC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CASrD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,GAC3B,YAAY,CAKd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAKrE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAG/E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,CAGpF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAehF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -21,5 +21,9 @@
21
21
  * pkg-ops list
22
22
  * ```
23
23
  */
24
- export {};
24
+ export { loadConfig, saveConfig, parsePackageSpec, isValidPackageName, getPackageConfig, updatePackageConfig, removePackageConfig, listManagedPackages, getConfigPath, ensureConfigDir, type PackageConfig, type PkgOpsConfig, } from "./config.js";
25
+ export { ServiceManager, getServiceManager, type ServiceInfo, type ServiceLogsOptions, } from "./service-manager.js";
26
+ export { RustBridge, startBridge, stopBridge, getBridge, type InstallResult, type PackageInfo, type RollbackResult, type VerifyResult, type AuditResult, type BundleSize, type InstalledPackageInfo, type VersionInfo, type SwitchResult, type PruneResult, } from "./bridge.js";
27
+ export { getInstalledVersions, isVersionInstalled, getActiveVersion, addPackageVersion, removePackageVersion, setActiveVersion, getVersionCount, getPackagesWithMultipleVersions, type VersionMetadata, } from "./config.js";
28
+ export { startHealthServer, stopHealthServer, getHealthServer, HealthServer, type HealthCheckResult, type ServiceHealth, type SystemHealth, } from "./health-server.js";
25
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA6kCH,OAAO,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,UAAU,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,+BAA+B,EAC/B,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,18 +1,21 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{readFileSync as j0,existsSync as l0}from"fs";import{constants as R,mkdirSync as U0,readFileSync as _0,writeFileSync as O0,existsSync as l}from"node:fs";import{dirname as V0}from"node:path";var f={packages:{},healthPort:8914,workDir:"/root",logLevel:"info"},A0="/etc/pkg-ops",R0=`${A0}/config.json`;function h(){return process.env.PKG_OPS_CONFIG??R0}function L0(){let $=V0(h());if(!l($))U0($,{recursive:!0,mode:R.S_IRWXU|R.S_IRGRP|R.S_IXGRP})}function L(){let $=h();try{if(!l($))return{...f};let Y=_0($,"utf-8"),W=JSON.parse(Y);return{...f,...W}}catch(Y){return console.error(`Failed to load config from ${$}:`,Y),{...f}}}function F0($){let Y=h();L0();let W=JSON.stringify($,null,2);O0(Y,W,{encoding:"utf-8",mode:R.S_IRUSR|R.S_IWUSR|R.S_IRGRP})}function I($,Y){let W=L();return W.packages[$]=Y,F0(W),W}function x($){return L().packages[$]}function m(){let $=L();return Object.entries($.packages).map(([Y,W])=>({name:Y,config:W}))}function y($){return $.startsWith("@ebowwa/")}function o($){let Y=$.lastIndexOf("@");if(Y<=0)return{name:$,version:"latest"};let W=$.slice(0,Y),X=$.slice(Y+1);if(!X)return{name:W,version:"latest"};return{name:W,version:X}}var{getPrototypeOf:J1,defineProperty:x0,getOwnPropertyNames:K1,getOwnPropertyDescriptor:E1}=Object;var y0=($,Y)=>{for(var W in Y)x0($,W,{get:Y[W],enumerable:!0,configurable:!0,set:(X)=>Y[W]=()=>X})},b0=($,Y)=>()=>($&&(Y=$($=0)),Y),c={};y0(c,{writeFile:()=>G0,sudo:()=>b,pkgInstall:()=>I0,exec:()=>i});async function b($,Y){let W=Array.isArray($)?$:$.split(/\s+/),X=["sudo",...Y.env?Object.entries(Y.env).map(([Z,q])=>`${Z}=${B(q)}`):[],...W];return i(X,Y)}async function I0($,Y){let W=Y.pm??"apt",X={...Y.env,...Y.nonInteractive!==!1?{DEBIAN_FRONTEND:"noninteractive"}:{}};return await b(n[W],{...Y,env:X,quiet:!0}),b([...t[W],...$],{...Y,env:X})}async function G0($,Y,W){let X=`tee ${W.append?"-a":""} ${B($)}`.trim(),Z=await M0(Y,["sudo",X],W);if(Z.ok&&W.mode)await b(["chmod",W.mode,$],W);if(Z.ok&&W.owner)await b(["chown",W.owner,$],W);return Z}function g($){let Y=["ssh","-F","/dev/null","-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null"];if($.keyPath)Y.push("-i",$.keyPath);else if($.key)Y.push("-i",$.key);if($.port)Y.push("-p",String($.port));return Y.push(`${$.user??"root"}@${$.host}`),Y}async function i($,Y){let W=Y.context??{type:"local"},X=W.type==="ssh"?[...g(W),$.map(B).join(" ")]:$,Z=Bun.spawn(X,{stdout:"pipe",stderr:"pipe",timeout:Y.timeout??30000}),q=await Z.exited,Q=Y.quiet?"":await new Response(Z.stdout).text(),w=await new Response(Z.stderr).text();return{stdout:Q,stderr:w,exitCode:q,ok:q===0}}async function M0($,Y,W){let X=W.context??{type:"local"};if(X.type==="ssh"){let K=g(X),z=Y.join(" "),V=[...K,z],J=Bun.spawn(V,{stdin:new TextEncoder().encode($),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),A=await J.exited,U=W.quiet?"":await new Response(J.stdout).text(),_=await new Response(J.stderr).text();return{stdout:U,stderr:_,exitCode:A,ok:A===0}}let Z=Bun.spawn(["sh","-c",Y.join(" ")],{stdin:new TextEncoder().encode($),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),q=await Z.exited,Q=W.quiet?"":await new Response(Z.stdout).text(),w=await new Response(Z.stderr).text();return{stdout:Q,stderr:w,exitCode:q,ok:q===0}}function B($){if(/^[a-zA-Z0-9._\-\/=:@]+$/.test($))return $;return`'${$.replace(/'/g,"'\\''")}'`}var t,n,P0=b0(()=>{t={apt:["apt-get","install","-y"],dnf:["dnf","install","-y"],apk:["apk","add","--no-cache"]},n={apt:["apt-get","update","-qq"],dnf:["dnf","check-update"],apk:["apk","update"]}});async function O($,Y){let{sudo:W}=await Promise.resolve().then(()=>(P0(),c));return W($,Y)}async function G($,Y){return O(["systemctl","enable",$],Y)}async function M($,Y){return O(["systemctl","disable",$],Y)}async function P($,Y){return O(["systemctl","start",$],Y)}async function D($,Y){return O(["systemctl","stop",$],Y)}async function C($,Y){return O(["systemctl","restart",$],Y)}async function S($,Y){let W=await O(["systemctl","show",$,"--property=LoadState,ActiveState,SubState,MainPID,Description"],{...Y});if(!W.ok)return{loaded:!1,active:!1,subState:"unknown",mainPid:0,description:""};let X=(Z)=>{return W.stdout.match(new RegExp(`^${Z}=(.+)$`,"m"))?.[1]?.trim()??""};return{loaded:X("LoadState")==="loaded",active:X("ActiveState")==="active",subState:X("SubState"),mainPid:parseInt(X("MainPID")||"0",10),description:X("Description")}}async function N($,Y){let W=await O(["systemctl","list-unit-files",$+".service"],Y);return W.ok&&W.stdout.includes($)}async function k($,Y={}){let W=["journalctl","-u",$,"-n",String(Y.lines??100)];if(Y.since)W.push("--since",Y.since);if(!Y.follow)W.push("-n",String(Y.lines??100));return(await O(W,Y)).stdout}class r{sudoOptions;constructor($){this.sudoOptions=$??{context:{type:"local"}}}async start($){let Y=await P($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} started`:Y.stderr||Y.stdout}}async stop($){let Y=await D($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} stopped`:Y.stderr||Y.stdout}}async restart($){let Y=await C($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} restarted`:Y.stderr||Y.stdout}}async status($){return S($,this.sudoOptions)}async enable($){let Y=await G($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} enabled`:Y.stderr||Y.stdout}}async disable($){let Y=await M($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} disabled`:Y.stderr||Y.stdout}}async exists($){return N($,this.sudoOptions)}async logs($,Y){return k($,{...this.sudoOptions,lines:Y?.lines??100,since:Y?.since})}async info($){let[Y,W]=await Promise.all([this.exists($),this.status($)]);return{name:$,exists:Y,status:W}}async isHealthy($){let Y=await this.status($);return Y.active&&Y.subState==="running"}async waitForHealthy($,Y){let W=Y?.timeout??30000,X=Y?.interval??1000,Z=Date.now();while(Date.now()-Z<W){if(await this.isHealthy($))return!0;await new Promise((Q)=>setTimeout(Q,X))}return!1}}var v=null;function E(){if(!v)v=new r;return v}import{spawn as D0}from"child_process";import{accessSync as s,constants as a}from"fs";import{join as u,dirname as C0}from"path";import{fileURLToPath as S0}from"url";var N0=30000;class e{process=null;pendingRequests=new Map;requestId=0;buffer="";async start(){if(this.process)return;let $=this.getBinaryPath();try{s($,a.X_OK)}catch{throw Error(`Rust binary not found at ${$}. Run 'bun run build:rust' in the pkg-ops package.`)}if(this.process=D0($,[],{stdio:["pipe","pipe","pipe"]}),!this.process.stdin||!this.process.stdout)throw Error("Failed to create stdin/stdout pipes");this.process.stdout.on("data",(Y)=>{this.buffer+=Y.toString("utf-8"),this.processBuffer()}),this.process.stderr?.on("data",(Y)=>{console.error("[rust-worker]",Y.toString("utf-8").trim())}),this.process.on("exit",(Y)=>{console.error(`Rust worker exited with code ${Y}`),this.process=null})}async stop(){if(!this.process)return;try{await this.sendRequest("shutdown",{})}catch{}if(await new Promise(($)=>setTimeout($,1000)),this.process)this.process.kill("SIGTERM"),this.process=null;for(let[$,Y]of this.pendingRequests)clearTimeout(Y.timeout),Y.reject(Error("Bridge shutdown"));this.pendingRequests.clear()}async install($,Y){return this.sendRequest("install",{packageName:$,version:Y})}async update($){return this.sendRequest("update",{packageName:$})}async updateAll(){return this.sendRequest("updateAll",{})}async list(){return this.sendRequest("list",{})}async rollback($){return this.sendRequest("rollback",{packageName:$})}async health(){return this.sendRequest("health",{})}async verify($){return this.sendRequest("verify",{packageName:$})}async audit(){return this.sendRequest("audit",{})}async getBundleSizes(){return this.sendRequest("sizes",{})}async getInstalledInfo(){return this.sendRequest("installedInfo",{})}getBinaryPath(){let $=C0(S0(import.meta.url)),Y=[u($,"..","rust","target","release","pkg-ops-core"),u($,"..","rust","pkg-ops-core"),u($,"..","rust","target","x86_64-unknown-linux-gnu","release","pkg-ops-core")];for(let W of Y)try{return s(W,a.X_OK),W}catch{}throw Error(`Rust binary not found. Tried:
3
+ import{readFileSync as a0,existsSync as e0}from"fs";import{constants as I,mkdirSync as L0,readFileSync as F0,writeFileSync as V0,existsSync as s}from"node:fs";import{dirname as y0}from"node:path";var v={packages:{},healthPort:8914,workDir:"/root",logLevel:"info"},x0="/etc/pkg-ops",I0=`${x0}/config.json`;function S(){return process.env.PKG_OPS_CONFIG??I0}function a(){let $=y0(S());if(!s($))L0($,{recursive:!0,mode:I.S_IRWXU|I.S_IRGRP|I.S_IXGRP})}function E(){let $=S();try{if(!s($))return{...v};let Y=F0($,"utf-8"),W=JSON.parse(Y);return{...v,...W}}catch(Y){return console.error(`Failed to load config from ${$}:`,Y),{...v}}}function b($){let Y=S();a();let W=JSON.stringify($,null,2);V0(Y,W,{encoding:"utf-8",mode:I.S_IRUSR|I.S_IWUSR|I.S_IRGRP})}function M($,Y){let W=E();return W.packages[$]=Y,b(W),W}function b0($){let Y=E();return delete Y.packages[$],b(Y),Y}function O($){return E().packages[$]}function d(){let $=E();return Object.entries($.packages).map(([Y,W])=>({name:Y,config:W}))}function T($){return $.startsWith("@ebowwa/")}function D($){let Y=$.lastIndexOf("@");if(Y<=0)return{name:$,version:"latest"};let W=$.slice(0,Y),X=$.slice(Y+1);if(!X)return{name:W,version:"latest"};return{name:W,version:X}}function G0($){let W=E().packages[$];if(!W?.versions)return[];return Object.entries(W.versions).map(([X,Z])=>({version:X,...Z}))}function M0($,Y){return!!E().packages[$]?.versions?.[Y]}function D0($){return E().packages[$]?.version??null}function P0($,Y,W){let X=E();if(!X.packages[$])X.packages[$]={version:Y,versions:{},service:$.replace("@ebowwa/",""),autoStart:!0};X.packages[$].versions[Y]={installedAt:W.installedAt??new Date().toISOString(),distSizeBytes:W.distSizeBytes??null,fileCount:W.fileCount??null},b(X)}function S0($,Y){let W=E(),X=W.packages[$];if(!X?.versions?.[Y])return!1;if(delete X.versions[Y],X.version===Y){let Z=Object.keys(X.versions).sort((q,Q)=>{let H=X.versions[q]?.installedAt??"";return(X.versions[Q]?.installedAt??"").localeCompare(H)});if(Z.length>0)X.version=Z[0];else delete W.packages[$]}return b(W),!0}function z0($,Y){let W=E(),X=W.packages[$];if(!X?.versions?.[Y])return!1;return X.version=Y,b(W),!0}function C0($){let W=E().packages[$];return Object.keys(W?.versions??{}).length}function h0(){let $=E(),Y=[];for(let[W,X]of Object.entries($.packages)){let Z=Object.keys(X.versions??{});if(Z.length>1)Y.push({name:W,activeVersion:X.version,totalVersions:Z.length,versions:Z.sort((q,Q)=>Q.localeCompare(q,void 0,{numeric:!0}))})}return Y}var{getPrototypeOf:b1,defineProperty:B0,getOwnPropertyNames:G1,getOwnPropertyDescriptor:M1}=Object;var N0=($,Y)=>{for(var W in Y)B0($,W,{get:Y[W],enumerable:!0,configurable:!0,set:(X)=>Y[W]=()=>X})},u0=($,Y)=>()=>($&&(Y=$($=0)),Y),e={};N0(e,{writeFile:()=>f0,sudo:()=>P,pkgInstall:()=>k0,exec:()=>$0});async function P($,Y){let W=Array.isArray($)?$:$.split(/\s+/),X=["sudo",...Y.env?Object.entries(Y.env).map(([Z,q])=>`${Z}=${j(q)}`):[],...W];return $0(X,Y)}async function k0($,Y){let W=Y.pm??"apt",X={...Y.env,...Y.nonInteractive!==!1?{DEBIAN_FRONTEND:"noninteractive"}:{}};return await P(X0[W],{...Y,env:X,quiet:!0}),P([...W0[W],...$],{...Y,env:X})}async function f0($,Y,W){let X=`tee ${W.append?"-a":""} ${j($)}`.trim(),Z=await v0(Y,["sudo",X],W);if(Z.ok&&W.mode)await P(["chmod",W.mode,$],W);if(Z.ok&&W.owner)await P(["chown",W.owner,$],W);return Z}function Y0($){let Y=["ssh","-F","/dev/null","-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null"];if($.keyPath)Y.push("-i",$.keyPath);else if($.key)Y.push("-i",$.key);if($.port)Y.push("-p",String($.port));return Y.push(`${$.user??"root"}@${$.host}`),Y}async function $0($,Y){let W=Y.context??{type:"local"},X=W.type==="ssh"?[...Y0(W),$.map(j).join(" ")]:$,Z=Bun.spawn(X,{stdout:"pipe",stderr:"pipe",timeout:Y.timeout??30000}),q=await Z.exited,Q=Y.quiet?"":await new Response(Z.stdout).text(),H=await new Response(Z.stderr).text();return{stdout:Q,stderr:H,exitCode:q,ok:q===0}}async function v0($,Y,W){let X=W.context??{type:"local"};if(X.type==="ssh"){let K=Y0(X),V=Y.join(" "),y=[...K,V],w=Bun.spawn(y,{stdin:new TextEncoder().encode($),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),x=await w.exited,A=W.quiet?"":await new Response(w.stdout).text(),R=await new Response(w.stderr).text();return{stdout:A,stderr:R,exitCode:x,ok:x===0}}let Z=Bun.spawn(["sh","-c",Y.join(" ")],{stdin:new TextEncoder().encode($),stdout:"pipe",stderr:"pipe",timeout:W.timeout??30000}),q=await Z.exited,Q=W.quiet?"":await new Response(Z.stdout).text(),H=await new Response(Z.stderr).text();return{stdout:Q,stderr:H,exitCode:q,ok:q===0}}function j($){if(/^[a-zA-Z0-9._\-\/=:@]+$/.test($))return $;return`'${$.replace(/'/g,"'\\''")}'`}var W0,X0,d0=u0(()=>{W0={apt:["apt-get","install","-y"],dnf:["dnf","install","-y"],apk:["apk","add","--no-cache"]},X0={apt:["apt-get","update","-qq"],dnf:["dnf","check-update"],apk:["apk","update"]}});async function L($,Y){let{sudo:W}=await Promise.resolve().then(()=>(d0(),e));return W($,Y)}async function z($,Y){return L(["systemctl","enable",$],Y)}async function C($,Y){return L(["systemctl","disable",$],Y)}async function h($,Y){return L(["systemctl","start",$],Y)}async function B($,Y){return L(["systemctl","stop",$],Y)}async function N($,Y){return L(["systemctl","restart",$],Y)}async function u($,Y){let W=await L(["systemctl","show",$,"--property=LoadState,ActiveState,SubState,MainPID,Description"],{...Y});if(!W.ok)return{loaded:!1,active:!1,subState:"unknown",mainPid:0,description:""};let X=(Z)=>{return W.stdout.match(new RegExp(`^${Z}=(.+)$`,"m"))?.[1]?.trim()??""};return{loaded:X("LoadState")==="loaded",active:X("ActiveState")==="active",subState:X("SubState"),mainPid:parseInt(X("MainPID")||"0",10),description:X("Description")}}async function k($,Y){let W=await L(["systemctl","list-unit-files",$+".service"],Y);return W.ok&&W.stdout.includes($)}async function f($,Y={}){let W=["journalctl","-u",$,"-n",String(Y.lines??100)];if(Y.since)W.push("--since",Y.since);if(!Y.follow)W.push("-n",String(Y.lines??100));return(await L(W,Y)).stdout}class l{sudoOptions;constructor($){this.sudoOptions=$??{context:{type:"local"}}}async start($){let Y=await h($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} started`:Y.stderr||Y.stdout}}async stop($){let Y=await B($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} stopped`:Y.stderr||Y.stdout}}async restart($){let Y=await N($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} restarted`:Y.stderr||Y.stdout}}async status($){return u($,this.sudoOptions)}async enable($){let Y=await z($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} enabled`:Y.stderr||Y.stdout}}async disable($){let Y=await C($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} disabled`:Y.stderr||Y.stdout}}async exists($){return k($,this.sudoOptions)}async logs($,Y){return f($,{...this.sudoOptions,lines:Y?.lines??100,since:Y?.since})}async info($){let[Y,W]=await Promise.all([this.exists($),this.status($)]);return{name:$,exists:Y,status:W}}async isHealthy($){let Y=await this.status($);return Y.active&&Y.subState==="running"}async waitForHealthy($,Y){let W=Y?.timeout??30000,X=Y?.interval??1000,Z=Date.now();while(Date.now()-Z<W){if(await this.isHealthy($))return!0;await new Promise((Q)=>setTimeout(Q,X))}return!1}}var p=null;function _(){if(!p)p=new l;return p}import{spawn as j0}from"child_process";import{accessSync as Z0,constants as q0}from"fs";import{join as m,dirname as p0}from"path";import{fileURLToPath as l0}from"url";var m0=30000;class c{process=null;pendingRequests=new Map;requestId=0;buffer="";async start(){if(this.process)return;let $=this.getBinaryPath();try{Z0($,q0.X_OK)}catch{throw Error(`Rust binary not found at ${$}. Run 'bun run build:rust' in the pkg-ops package.`)}if(this.process=j0($,[],{stdio:["pipe","pipe","pipe"]}),!this.process.stdin||!this.process.stdout)throw Error("Failed to create stdin/stdout pipes");this.process.stdout.on("data",(Y)=>{this.buffer+=Y.toString("utf-8"),this.processBuffer()}),this.process.stderr?.on("data",(Y)=>{console.error("[rust-worker]",Y.toString("utf-8").trim())}),this.process.on("exit",(Y)=>{console.error(`Rust worker exited with code ${Y}`),this.process=null})}async stop(){if(!this.process)return;try{await this.sendRequest("shutdown",{})}catch{}if(await new Promise(($)=>setTimeout($,1000)),this.process)this.process.kill("SIGTERM"),this.process=null;for(let[$,Y]of this.pendingRequests)clearTimeout(Y.timeout),Y.reject(Error("Bridge shutdown"));this.pendingRequests.clear()}async install($,Y){return this.sendRequest("install",{packageName:$,version:Y})}async update($){return this.sendRequest("update",{packageName:$})}async updateAll(){return this.sendRequest("updateAll",{})}async list(){return this.sendRequest("list",{})}async rollback($){return this.sendRequest("rollback",{packageName:$})}async health(){return this.sendRequest("health",{})}async verify($){return this.sendRequest("verify",{packageName:$})}async audit(){return this.sendRequest("audit",{})}async getBundleSizes(){return this.sendRequest("sizes",{})}async getInstalledInfo(){return this.sendRequest("installedInfo",{})}async listVersions($){return this.sendRequest("listVersions",{packageName:$})}async switchVersion($,Y){return this.sendRequest("switchVersion",{packageName:$,version:Y})}async pruneVersions($,Y){return this.sendRequest("pruneVersions",{packageName:$,keepCount:Y})}async removeVersion($,Y){return this.sendRequest("removeVersion",{packageName:$,version:Y})}async getMultiVersionPackages(){return this.sendRequest("getMultiVersionPackages",{})}getBinaryPath(){let $=p0(l0(import.meta.url)),Y=[m($,"..","rust","target","release","pkg-ops-core"),m($,"..","rust","pkg-ops-core"),m($,"..","rust","target","x86_64-unknown-linux-gnu","release","pkg-ops-core")];for(let W of Y)try{return Z0(W,q0.X_OK),W}catch{}throw Error(`Rust binary not found. Tried:
4
4
  ${Y.map((W)=>` - ${W}`).join(`
5
5
  `)}
6
- Run 'bun run build:rust' or 'cargo build --release' in the pkg-ops package.`)}sendRequest($,Y){return new Promise((W,X)=>{if(!this.process?.stdin){X(Error("Rust worker not started"));return}let Z=String(++this.requestId),q={jsonrpc:"2.0",id:Z,method:$,params:Y},Q=setTimeout(()=>{this.pendingRequests.delete(Z),X(Error(`Request timeout: ${$}`))},N0);this.pendingRequests.set(Z,{resolve:W,reject:X,timeout:Q});let w=JSON.stringify(q)+`
7
- `;this.process.stdin.write(w,"utf-8",(K)=>{if(K)this.pendingRequests.delete(Z),clearTimeout(Q),X(K)})})}processBuffer(){let $=this.buffer.split(`
8
- `);this.buffer=$.pop()??"";for(let Y of $){if(!Y.trim())continue;try{let W=JSON.parse(Y),X=this.pendingRequests.get(W.id);if(X)if(clearTimeout(X.timeout),this.pendingRequests.delete(W.id),W.error)X.reject(Error(W.error.message));else X.resolve(W.result)}catch(W){console.error("Failed to parse response:",Y,W)}}}}var F=null;function k0(){if(!F)F=new e;return F}async function H(){let $=k0();return await $.start(),$}async function T(){if(F)await F.stop(),F=null}import{createServer as u0}from"http";class Y0{sudoOptions;constructor($){this.sudoOptions=$??{context:{type:"local"}}}async start($){let Y=await P($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} started`:Y.stderr||Y.stdout}}async stop($){let Y=await D($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} stopped`:Y.stderr||Y.stdout}}async restart($){let Y=await C($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} restarted`:Y.stderr||Y.stdout}}async status($){return S($,this.sudoOptions)}async enable($){let Y=await G($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} enabled`:Y.stderr||Y.stdout}}async disable($){let Y=await M($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} disabled`:Y.stderr||Y.stdout}}async exists($){return N($,this.sudoOptions)}async logs($,Y){return k($,{...this.sudoOptions,lines:Y?.lines??100,since:Y?.since})}async info($){let[Y,W]=await Promise.all([this.exists($),this.status($)]);return{name:$,exists:Y,status:W}}async isHealthy($){let Y=await this.status($);return Y.active&&Y.subState==="running"}async waitForHealthy($,Y){let W=Y?.timeout??30000,X=Y?.interval??1000,Z=Date.now();while(Date.now()-Z<W){if(await this.isHealthy($))return!0;await new Promise((Q)=>setTimeout(Q,X))}return!1}}var p=null;function d(){if(!p)p=new Y0;return p}import{constants as b1,mkdirSync as I1,readFileSync as z0,writeFileSync as G1,existsSync as f0}from"node:fs";var j={packages:{},healthPort:8914,workDir:"/root",logLevel:"info"},h0="/etc/pkg-ops",B0=`${h0}/config.json`;function v0(){return process.env.PKG_OPS_CONFIG??B0}function $0(){let $=v0();try{if(!f0($))return{...j};let Y=z0($,"utf-8"),W=JSON.parse(Y);return{...j,...W}}catch(Y){return console.error(`Failed to load config from ${$}:`,Y),{...j}}}class p0{server=null;checks=new Map;startTime=Date.now();port;constructor($=8914){this.port=$}async start(){if(this.server)return;return new Promise(($,Y)=>{this.server=u0((W,X)=>this.handleRequest(W,X)),this.server.on("error",Y),this.server.listen(this.port,()=>{console.log(`Health server listening on port ${this.port}`),this.server?.off("error",Y),$()})})}async stop(){if(!this.server)return;return new Promise(($)=>{this.server?.close(()=>{this.server=null,$()})})}addCheck($,Y){this.checks.set($,Y)}removeCheck($){this.checks.delete($)}async checkHealth($){if($)return this.getServiceHealth($);return this.getSystemHealth()}async handleRequest($,Y){let W=$.url??"/",X=$.method??"GET";try{if(X==="GET"&&W==="/health"){let Z=await this.getSystemHealth();this.sendJson(Y,200,Z)}else if(X==="GET"&&W.startsWith("/health/")){let Z=W.slice(8).replace(".service",""),q=await this.getServiceHealth(Z);this.sendJson(Y,q?200:404,q??{error:"Service not found"})}else if(X==="GET"&&W==="/ready"){let Z=await this.getSystemHealth();this.sendJson(Y,Z.healthy?200:503,{ready:Z.healthy})}else if(X==="GET"&&W==="/live")this.sendJson(Y,200,{alive:!0});else this.sendJson(Y,404,{error:"Not found"})}catch(Z){console.error("Health check error:",Z),this.sendJson(Y,500,{error:"Internal server error"})}}async getSystemHealth(){let $=$0(),Y=d(),W=[];for(let[q,Q]of Object.entries($.packages)){if(!Q.service)continue;let w=await Y.status(Q.service),K=w.active&&w.subState==="running";W.push({name:Q.service,healthy:K,status:w,checkedAt:new Date().toISOString()})}let X={};for(let[q,Q]of this.checks)try{X[q]=await Q()}catch(w){X[q]={healthy:!1,message:w instanceof Error?w.message:"Unknown error"}}return{healthy:W.every((q)=>q.healthy)&&Object.values(X).every((q)=>q.healthy),services:W,uptime:Math.floor((Date.now()-this.startTime)/1000),timestamp:new Date().toISOString()}}async getServiceHealth($){let Y=d();if(!await Y.exists($))return null;let X=await Y.status($),Z=X.active&&X.subState==="running";return{name:$,healthy:Z,status:X,checkedAt:new Date().toISOString()}}sendJson($,Y,W){$.statusCode=Y,$.setHeader("Content-Type","application/json"),$.end(JSON.stringify(W,null,2))}}var d0=null;function W0(){return d0}async function m0($){if($.length===0)console.error("Usage: pkg-ops install <package>[@version]"),process.exit(1);let Y=$[0],{name:W,version:X}=o(Y);if(!y(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Installing ${W}@${X}...`);try{let q=await(await H()).install(W,X);if(q.success){if(console.log(`Successfully installed ${W}@${q.version}`),q.previousVersion)console.log(` Previous version: ${q.previousVersion}`);I(W,{version:q.version,service:W.replace("@ebowwa/","")});let Q=x(W);if(Q?.service&&Q.autoStart!==!1){let K=await E().start(Q.service);if(K.success)console.log(` Service ${Q.service} started`);else console.warn(` Failed to start service: ${K.message}`)}}else console.error(`Failed to install ${W}: ${q.message}`),process.exit(1)}catch(Z){console.error("Install failed:",Z),process.exit(1)}finally{await T()}}async function o0($){if($.length===0)console.error("Usage: pkg-ops update <package>"),process.exit(1);let Y=$[0];if(!y(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Updating ${Y}...`);try{let X=await(await H()).update(Y);if(X.success){if(console.log(`Successfully updated ${Y} to ${X.version}`),X.previousVersion)console.log(` Previous version: ${X.previousVersion}`);I(Y,{version:X.version,service:Y.replace("@ebowwa/","")});let Z=E(),q=x(Y);if(q?.service){if((await Z.status(q.service)).active)await Z.restart(q.service),console.log(` Service ${q.service} restarted`)}}else console.error(`Failed to update ${Y}: ${X.message}`),process.exit(1)}catch(W){console.error("Update failed:",W),process.exit(1)}finally{await T()}}async function c0($){console.log("Updating all managed packages...");try{let W=await(await H()).updateAll();for(let X of W)if(X.success)console.log(`Updated ${X.version}`);else console.error(`Failed to update: ${X.message}`)}catch(Y){console.error("Update all failed:",Y),process.exit(1)}finally{await T()}}async function g0($){console.log(`Installed packages:
9
- `);try{let W=await(await H()).list();if(W.length===0){console.log(" No packages installed");return}for(let X of W){let Z=X.installed?"installed":"not installed",q=X.service?` (service: ${X.service})`:"";console.log(` ${X.name}@${X.version} [${Z}]${q}`)}}catch(Y){console.error("Failed to list packages:",Y),process.exit(1)}finally{await T()}}async function i0($){if($.length===0)console.error("Usage: pkg-ops rollback <package>"),process.exit(1);let Y=$[0];console.log(`Rolling back ${Y}...`);try{let X=await(await H()).rollback(Y);if(X.success){console.log(`Rolled back ${Y} from ${X.currentVersion} to ${X.previousVersion}`);let Z=E(),q=x(Y);if(q?.service){if((await Z.status(q.service)).active)await Z.restart(q.service),console.log(` Service ${q.service} restarted`)}}else console.error(`Rollback failed: ${X.message}`),process.exit(1)}catch(W){console.error("Rollback failed:",W),process.exit(1)}finally{await T()}}async function X0($){if($.length===0)console.error("Usage: pkg-ops service start <name>"),process.exit(1);let Y=$[0],W=E();console.log(`Starting ${Y}...`);let X=await W.start(Y);if(X.success)console.log(`Service ${Y} started`);else console.error(`Failed to start ${Y}: ${X.message}`),process.exit(1)}async function Z0($){if($.length===0)console.error("Usage: pkg-ops service stop <name>"),process.exit(1);let Y=$[0],W=E();console.log(`Stopping ${Y}...`);let X=await W.stop(Y);if(X.success)console.log(`Service ${Y} stopped`);else console.error(`Failed to stop ${Y}: ${X.message}`),process.exit(1)}async function q0($){if($.length===0)console.error("Usage: pkg-ops service restart <name>"),process.exit(1);let Y=$[0],W=E();console.log(`Restarting ${Y}...`);let X=await W.restart(Y);if(X.success)console.log(`Service ${Y} restarted`);else console.error(`Failed to restart ${Y}: ${X.message}`),process.exit(1)}async function Q0($){if($.length===0)console.error("Usage: pkg-ops service status <name>"),process.exit(1);let Y=$[0],X=await E().info(Y);if(!X.exists){console.log(`Service ${Y} not found`);return}console.log(`Service: ${Y}`),console.log(` Loaded: ${X.status.loaded}`),console.log(` Active: ${X.status.active}`),console.log(` State: ${X.status.subState}`),console.log(` PID: ${X.status.mainPid||"N/A"}`),console.log(` Description: ${X.status.description||"N/A"}`)}async function w0($){if($.length===0)console.error("Usage: pkg-ops service logs <name> [--lines N]"),process.exit(1);let Y=$[0],W=$.indexOf("--lines"),X=W>=0&&$[W+1]?parseInt($[W+1],10):100,q=await E().logs(Y,{lines:X});console.log(q)}async function J0($){if($.length===0)console.error("Usage: pkg-ops service enable <name>"),process.exit(1);let Y=$[0],W=E();console.log(`Enabling ${Y}...`);let X=await W.enable(Y);if(X.success)console.log(`Service ${Y} enabled on boot`);else console.error(`Failed to enable ${Y}: ${X.message}`),process.exit(1)}async function K0($){if($.length===0)console.error("Usage: pkg-ops service disable <name>"),process.exit(1);let Y=$[0],W=E();console.log(`Disabling ${Y}...`);let X=await W.disable(Y);if(X.success)console.log(`Service ${Y} disabled from boot`);else console.error(`Failed to disable ${Y}: ${X.message}`),process.exit(1)}async function t0($){let Y=$[0],W=W0();if(!W)console.error("Health server not initialized"),process.exit(1);let X=await W.checkHealth(Y);if(!X){console.log("Service not found");return}if("services"in X){if(X.healthy)console.log("All services healthy");else console.log("Some services unhealthy");for(let Z of X.services){let q=Z.healthy?"OK":"FAIL";console.log(` [${q}] ${Z.name}: ${Z.status.subState}`)}}else{let Z=X.healthy?"OK":"FAIL";console.log(`[${Z}] ${X.name}: ${X.status.subState}`)}}async function E0($){let Y=L();console.log("PkgOps Configuration"),console.log("Config path: /etc/pkg-ops/config.json"),console.log(`Health port: ${Y.healthPort}`),console.log(`Work dir: ${Y.workDir}`),console.log(`Log level: ${Y.logLevel}`),console.log(`
10
- Packages:`);let W=m();if(W.length===0){console.log(" No packages configured");return}for(let{name:X,config:Z}of W){if(console.log(` ${X}:`),console.log(` Version: ${Z.version}`),Z.service)console.log(` Service: ${Z.service}`);if(Z.autoStart!==void 0)console.log(` Auto-start: ${Z.autoStart}`)}}async function H0($){if($.length<3)console.error("Usage: pkg-ops config set <package> <key> <value>"),process.exit(1);let Y=$[0],W=$[1],X=$[2];if(!y(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);let Z=x(Y)??{version:"latest"};switch(W){case"version":Z.version=X;break;case"service":Z.service=X;break;case"autoStart":Z.autoStart=X==="true";break;default:console.error(`Unknown config key: ${W}`),console.error("Valid keys: version, service, autoStart"),process.exit(1)}I(Y,Z),console.log(`Updated ${Y}.${W} = ${X}`)}async function n0($){if($.length===0)console.error("Usage: pkg-ops verify <package>"),process.exit(1);let Y=$[0];if(!y(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Verifying ${Y}...`);try{let X=await(await H()).verify(Y);if(console.log(`
11
- Package: ${X.packageName}@${X.version}`),console.log(` Status: ${X.success?"VALID":"INVALID"}`),console.log(` Dist exists: ${X.distExists?"Yes":"No"}`),X.checksum)console.log(` Checksum: ${X.checksum}`);console.log(` Message: ${X.message}`)}catch(W){console.error("Verification failed:",W),process.exit(1)}finally{await T()}}async function r0($){let Y=$.indexOf("--local"),W=$.indexOf("--local-path"),X="./package.json";if(W>=0&&$[W+1])X=$[W+1];let Z=Y>=0||W>=0;try{let Q=await(await H()).getInstalledInfo();if(console.log(`Sync Status: Local vs VPS
12
- `),Z&&l0(X)){let w=j0(X,"utf-8"),K=JSON.parse(w),z={...K.dependencies,...K.devDependencies},V=new Map;for(let J of Q)V.set(J.packageName,J.version);for(let[J,A]of Object.entries(z)){if(!J.startsWith("@ebowwa/"))continue;let U=V.get(J),_=A.replace(/^[\^~]/,"");if(U){if(_===U)console.log(` ${J}: local=${_}, vps=${U} (in sync)`);else if(_>U)console.log(` ${J}: local=${_}, vps=${U} (VPS behind)`);else console.log(` ${J}: local=${_}, vps=${U} (local behind)`);V.delete(J)}else console.log(` ${J}: local=${_}, vps=not installed`)}for(let[J,A]of V)console.log(` ${J}: local=not in package.json, vps=${A}`)}else if(Q.length===0)console.log(" No packages installed on VPS");else for(let w of Q){let K=w.distSizeBytes?` (${(w.distSizeBytes/1024).toFixed(1)} KB)`:"";console.log(` ${w.packageName}@${w.version}${K}`)}}catch(q){console.error("Failed to get sync status:",q),process.exit(1)}finally{await T()}}async function T0($){console.log(`Running vulnerability scan...
13
- `);try{let W=await(await H()).audit();if(W.length===0){console.log("No vulnerabilities found.");return}console.log(`Found ${W.length} vulnerability(es):
14
- `);for(let X of W)console.log(`[${X.severity.toUpperCase()}] ${X.packageName}`),console.log(` Vulnerability: ${X.vulnerability}`),console.log(` Description: ${X.description}`),console.log("")}catch(Y){console.error("Audit failed:",Y),process.exit(1)}finally{await T()}}async function s0($){await T0($)}async function a0($){console.log(`Bundle sizes:
15
- `);try{let W=await(await H()).getBundleSizes();if(W.length===0){console.log(" No packages installed");return}console.log(" Package | Version | Dist Size"),console.log(" --------------------------------|----------|-----------");for(let X of W){let Z=X.packageName.padEnd(32),q=X.version.padEnd(9),Q=(X.distSizeBytes/1024).toFixed(1)+" KB",w=X.fileCount?` (${X.fileCount} files)`:"";console.log(` ${Z} | ${q} | ${Q}${w}`)}}catch(Y){console.error("Failed to get bundle sizes:",Y),process.exit(1)}finally{await T()}}var e0=[{name:"install",description:"Install an @ebowwa/* package",usage:"pkg-ops install <package>[@version]",handler:m0},{name:"update",description:"Update a package to latest version",usage:"pkg-ops update <package>",handler:o0},{name:"update-all",description:"Update all managed packages",usage:"pkg-ops update-all",handler:c0},{name:"list",description:"List installed packages",usage:"pkg-ops list",handler:g0},{name:"rollback",description:"Rollback a package to previous version",usage:"pkg-ops rollback <package>",handler:i0},{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:X0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:Z0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:q0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:Q0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:w0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:J0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:K0},{name:"health",description:"Check health of all services",usage:"pkg-ops health [service]",handler:t0},{name:"config",description:"Show configuration",usage:"pkg-ops config show",handler:E0},{name:"set-config",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:H0},{name:"verify",description:"Verify package integrity",usage:"pkg-ops verify <package>",handler:n0},{name:"sync-status",description:"Show local vs VPS version sync",usage:"pkg-ops sync-status [--local-path path]",handler:r0},{name:"audit",description:"Check for vulnerabilities",usage:"pkg-ops audit",handler:T0},{name:"scan",description:"Alias for audit",usage:"pkg-ops scan",handler:s0},{name:"sizes",description:"Show bundle sizes",usage:"pkg-ops sizes",handler:a0}],Y1=[{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:X0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:Z0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:q0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:Q0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:w0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:J0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:K0}],$1=[{name:"show",description:"Show configuration",usage:"pkg-ops config show",handler:E0},{name:"set",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:H0}];function W1(){console.log(`
6
+ Run 'bun run build:rust' or 'cargo build --release' in the pkg-ops package.`)}sendRequest($,Y){return new Promise((W,X)=>{if(!this.process?.stdin){X(Error("Rust worker not started"));return}let Z=String(++this.requestId),q={jsonrpc:"2.0",id:Z,method:$,params:Y},Q=setTimeout(()=>{this.pendingRequests.delete(Z),X(Error(`Request timeout: ${$}`))},m0);this.pendingRequests.set(Z,{resolve:W,reject:X,timeout:Q});let H=JSON.stringify(q)+`
7
+ `;this.process.stdin.write(H,"utf-8",(K)=>{if(K)this.pendingRequests.delete(Z),clearTimeout(Q),X(K)})})}processBuffer(){let $=this.buffer.split(`
8
+ `);this.buffer=$.pop()??"";for(let Y of $){if(!Y.trim())continue;try{let W=JSON.parse(Y),X=this.pendingRequests.get(W.id);if(X)if(clearTimeout(X.timeout),this.pendingRequests.delete(W.id),W.error)X.reject(Error(W.error.message));else X.resolve(W.result)}catch(W){console.error("Failed to parse response:",Y,W)}}}}var G=null;function Q0(){if(!G)G=new c;return G}async function U(){let $=Q0();return await $.start(),$}async function J(){if(G)await G.stop(),G=null}import{createServer as n0}from"http";class H0{sudoOptions;constructor($){this.sudoOptions=$??{context:{type:"local"}}}async start($){let Y=await h($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} started`:Y.stderr||Y.stdout}}async stop($){let Y=await B($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} stopped`:Y.stderr||Y.stdout}}async restart($){let Y=await N($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} restarted`:Y.stderr||Y.stdout}}async status($){return u($,this.sudoOptions)}async enable($){let Y=await z($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} enabled`:Y.stderr||Y.stdout}}async disable($){let Y=await C($,this.sudoOptions);return{success:Y.ok,message:Y.ok?`Service ${$} disabled`:Y.stderr||Y.stdout}}async exists($){return k($,this.sudoOptions)}async logs($,Y){return f($,{...this.sudoOptions,lines:Y?.lines??100,since:Y?.since})}async info($){let[Y,W]=await Promise.all([this.exists($),this.status($)]);return{name:$,exists:Y,status:W}}async isHealthy($){let Y=await this.status($);return Y.active&&Y.subState==="running"}async waitForHealthy($,Y){let W=Y?.timeout??30000,X=Y?.interval??1000,Z=Date.now();while(Date.now()-Z<W){if(await this.isHealthy($))return!0;await new Promise((Q)=>setTimeout(Q,X))}return!1}}var o=null;function t(){if(!o)o=new H0;return o}import{constants as d1,mkdirSync as j1,readFileSync as c0,writeFileSync as p1,existsSync as o0}from"node:fs";var i={packages:{},healthPort:8914,workDir:"/root",logLevel:"info"},t0="/etc/pkg-ops",i0=`${t0}/config.json`;function g0(){return process.env.PKG_OPS_CONFIG??i0}function g(){let $=g0();try{if(!o0($))return{...i};let Y=c0($,"utf-8"),W=JSON.parse(Y);return{...i,...W}}catch(Y){return console.error(`Failed to load config from ${$}:`,Y),{...i}}}class n{server=null;checks=new Map;startTime=Date.now();port;constructor($=8914){this.port=$}async start(){if(this.server)return;return new Promise(($,Y)=>{this.server=n0((W,X)=>this.handleRequest(W,X)),this.server.on("error",Y),this.server.listen(this.port,()=>{console.log(`Health server listening on port ${this.port}`),this.server?.off("error",Y),$()})})}async stop(){if(!this.server)return;return new Promise(($)=>{this.server?.close(()=>{this.server=null,$()})})}addCheck($,Y){this.checks.set($,Y)}removeCheck($){this.checks.delete($)}async checkHealth($){if($)return this.getServiceHealth($);return this.getSystemHealth()}async handleRequest($,Y){let W=$.url??"/",X=$.method??"GET";try{if(X==="GET"&&W==="/health"){let Z=await this.getSystemHealth();this.sendJson(Y,200,Z)}else if(X==="GET"&&W.startsWith("/health/")){let Z=W.slice(8).replace(".service",""),q=await this.getServiceHealth(Z);this.sendJson(Y,q?200:404,q??{error:"Service not found"})}else if(X==="GET"&&W==="/ready"){let Z=await this.getSystemHealth();this.sendJson(Y,Z.healthy?200:503,{ready:Z.healthy})}else if(X==="GET"&&W==="/live")this.sendJson(Y,200,{alive:!0});else this.sendJson(Y,404,{error:"Not found"})}catch(Z){console.error("Health check error:",Z),this.sendJson(Y,500,{error:"Internal server error"})}}async getSystemHealth(){let $=g(),Y=t(),W=[];for(let[q,Q]of Object.entries($.packages)){if(!Q.service)continue;let H=await Y.status(Q.service),K=H.active&&H.subState==="running";W.push({name:Q.service,healthy:K,status:H,checkedAt:new Date().toISOString()})}let X={};for(let[q,Q]of this.checks)try{X[q]=await Q()}catch(H){X[q]={healthy:!1,message:H instanceof Error?H.message:"Unknown error"}}return{healthy:W.every((q)=>q.healthy)&&Object.values(X).every((q)=>q.healthy),services:W,uptime:Math.floor((Date.now()-this.startTime)/1000),timestamp:new Date().toISOString()}}async getServiceHealth($){let Y=t();if(!await Y.exists($))return null;let X=await Y.status($),Z=X.active&&X.subState==="running";return{name:$,healthy:Z,status:X,checkedAt:new Date().toISOString()}}sendJson($,Y,W){$.statusCode=Y,$.setHeader("Content-Type","application/json"),$.end(JSON.stringify(W,null,2))}}var F=null;async function r0($){let Y=g(),W=$??Y.healthPort??8914;if(!F)F=new n(W);return await F.start(),F}async function s0(){if(F)await F.stop(),F=null}function r(){return F}async function Y1($){if($.length===0)console.error("Usage: pkg-ops install <package>[@version]"),process.exit(1);let Y=$[0],{name:W,version:X}=D(Y);if(!T(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Installing ${W}@${X}...`);try{let q=await(await U()).install(W,X);if(q.success){if(console.log(`Successfully installed ${W}@${q.version}`),q.previousVersion)console.log(` Previous version: ${q.previousVersion}`);let Q=O(W);M(W,{version:q.version,versions:{...Q?.versions,[q.version]:{installedAt:new Date().toISOString(),distSizeBytes:null,fileCount:null}},service:W.replace("@ebowwa/","")});let H=O(W);if(H?.service&&H.autoStart!==!1){let V=await _().start(H.service);if(V.success)console.log(` Service ${H.service} started`);else console.warn(` Failed to start service: ${V.message}`)}}else console.error(`Failed to install ${W}: ${q.message}`),process.exit(1)}catch(Z){console.error("Install failed:",Z),process.exit(1)}finally{await J()}}async function $1($){if($.length===0)console.error("Usage: pkg-ops update <package>"),process.exit(1);let Y=$[0];if(!T(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Updating ${Y}...`);try{let X=await(await U()).update(Y);if(X.success){if(console.log(`Successfully updated ${Y} to ${X.version}`),X.previousVersion)console.log(` Previous version: ${X.previousVersion}`);let Z=O(Y);M(Y,{version:X.version,versions:{...Z?.versions,[X.version]:{installedAt:new Date().toISOString(),distSizeBytes:null,fileCount:null}},service:Y.replace("@ebowwa/","")});let q=_(),Q=O(Y);if(Q?.service){if((await q.status(Q.service)).active)await q.restart(Q.service),console.log(` Service ${Q.service} restarted`)}}else console.error(`Failed to update ${Y}: ${X.message}`),process.exit(1)}catch(W){console.error("Update failed:",W),process.exit(1)}finally{await J()}}async function W1($){console.log("Updating all managed packages...");try{let W=await(await U()).updateAll();for(let X of W)if(X.success)console.log(`Updated ${X.version}`);else console.error(`Failed to update: ${X.message}`)}catch(Y){console.error("Update all failed:",Y),process.exit(1)}finally{await J()}}async function X1($){console.log(`Installed packages:
9
+ `);try{let W=await(await U()).list();if(W.length===0){console.log(" No packages installed");return}for(let X of W){let Z=X.installed?"installed":"not installed",q=X.service?` (service: ${X.service})`:"";console.log(` ${X.name}@${X.version} [${Z}]${q}`)}}catch(Y){console.error("Failed to list packages:",Y),process.exit(1)}finally{await J()}}async function Z1($){if($.length===0)console.error("Usage: pkg-ops rollback <package>"),process.exit(1);let Y=$[0];console.log(`Rolling back ${Y}...`);try{let X=await(await U()).rollback(Y);if(X.success){console.log(`Rolled back ${Y} from ${X.currentVersion} to ${X.previousVersion}`);let Z=_(),q=O(Y);if(q?.service){if((await Z.status(q.service)).active)await Z.restart(q.service),console.log(` Service ${q.service} restarted`)}}else console.error(`Rollback failed: ${X.message}`),process.exit(1)}catch(W){console.error("Rollback failed:",W),process.exit(1)}finally{await J()}}async function J0($){if($.length===0)console.error("Usage: pkg-ops service start <name>"),process.exit(1);let Y=$[0],W=_();console.log(`Starting ${Y}...`);let X=await W.start(Y);if(X.success)console.log(`Service ${Y} started`);else console.error(`Failed to start ${Y}: ${X.message}`),process.exit(1)}async function K0($){if($.length===0)console.error("Usage: pkg-ops service stop <name>"),process.exit(1);let Y=$[0],W=_();console.log(`Stopping ${Y}...`);let X=await W.stop(Y);if(X.success)console.log(`Service ${Y} stopped`);else console.error(`Failed to stop ${Y}: ${X.message}`),process.exit(1)}async function w0($){if($.length===0)console.error("Usage: pkg-ops service restart <name>"),process.exit(1);let Y=$[0],W=_();console.log(`Restarting ${Y}...`);let X=await W.restart(Y);if(X.success)console.log(`Service ${Y} restarted`);else console.error(`Failed to restart ${Y}: ${X.message}`),process.exit(1)}async function E0($){if($.length===0)console.error("Usage: pkg-ops service status <name>"),process.exit(1);let Y=$[0],X=await _().info(Y);if(!X.exists){console.log(`Service ${Y} not found`);return}console.log(`Service: ${Y}`),console.log(` Loaded: ${X.status.loaded}`),console.log(` Active: ${X.status.active}`),console.log(` State: ${X.status.subState}`),console.log(` PID: ${X.status.mainPid||"N/A"}`),console.log(` Description: ${X.status.description||"N/A"}`)}async function U0($){if($.length===0)console.error("Usage: pkg-ops service logs <name> [--lines N]"),process.exit(1);let Y=$[0],W=$.indexOf("--lines"),X=W>=0&&$[W+1]?parseInt($[W+1],10):100,q=await _().logs(Y,{lines:X});console.log(q)}async function _0($){if($.length===0)console.error("Usage: pkg-ops service enable <name>"),process.exit(1);let Y=$[0],W=_();console.log(`Enabling ${Y}...`);let X=await W.enable(Y);if(X.success)console.log(`Service ${Y} enabled on boot`);else console.error(`Failed to enable ${Y}: ${X.message}`),process.exit(1)}async function O0($){if($.length===0)console.error("Usage: pkg-ops service disable <name>"),process.exit(1);let Y=$[0],W=_();console.log(`Disabling ${Y}...`);let X=await W.disable(Y);if(X.success)console.log(`Service ${Y} disabled from boot`);else console.error(`Failed to disable ${Y}: ${X.message}`),process.exit(1)}async function q1($){let Y=$[0],W=r();if(!W)console.error("Health server not initialized"),process.exit(1);let X=await W.checkHealth(Y);if(!X){console.log("Service not found");return}if("services"in X){if(X.healthy)console.log("All services healthy");else console.log("Some services unhealthy");for(let Z of X.services){let q=Z.healthy?"OK":"FAIL";console.log(` [${q}] ${Z.name}: ${Z.status.subState}`)}}else{let Z=X.healthy?"OK":"FAIL";console.log(`[${Z}] ${X.name}: ${X.status.subState}`)}}async function T0($){let Y=E();console.log("PkgOps Configuration"),console.log("Config path: /etc/pkg-ops/config.json"),console.log(`Health port: ${Y.healthPort}`),console.log(`Work dir: ${Y.workDir}`),console.log(`Log level: ${Y.logLevel}`),console.log(`
10
+ Packages:`);let W=d();if(W.length===0){console.log(" No packages configured");return}for(let{name:X,config:Z}of W){if(console.log(` ${X}:`),console.log(` Version: ${Z.version}`),Z.service)console.log(` Service: ${Z.service}`);if(Z.autoStart!==void 0)console.log(` Auto-start: ${Z.autoStart}`)}}async function A0($){if($.length<3)console.error("Usage: pkg-ops config set <package> <key> <value>"),process.exit(1);let Y=$[0],W=$[1],X=$[2];if(!T(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);let Z=O(Y)??{version:"latest",versions:{}};switch(W){case"version":Z.version=X;break;case"service":Z.service=X;break;case"autoStart":Z.autoStart=X==="true";break;default:console.error(`Unknown config key: ${W}`),console.error("Valid keys: version, service, autoStart"),process.exit(1)}M(Y,Z),console.log(`Updated ${Y}.${W} = ${X}`)}async function Q1($){if($.length===0)console.error("Usage: pkg-ops verify <package>"),process.exit(1);let Y=$[0];if(!T(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Verifying ${Y}...`);try{let X=await(await U()).verify(Y);if(console.log(`
11
+ Package: ${X.packageName}@${X.version}`),console.log(` Status: ${X.success?"VALID":"INVALID"}`),console.log(` Dist exists: ${X.distExists?"Yes":"No"}`),X.checksum)console.log(` Checksum: ${X.checksum}`);console.log(` Message: ${X.message}`)}catch(W){console.error("Verification failed:",W),process.exit(1)}finally{await J()}}async function H1($){let Y=$.indexOf("--local"),W=$.indexOf("--local-path"),X="./package.json";if(W>=0&&$[W+1])X=$[W+1];let Z=Y>=0||W>=0;try{let Q=await(await U()).getInstalledInfo();if(console.log(`Sync Status: Local vs VPS
12
+ `),Z&&e0(X)){let H=a0(X,"utf-8"),K=JSON.parse(H),V={...K.dependencies,...K.devDependencies},y=new Map;for(let w of Q)y.set(w.packageName,w.version);for(let[w,x]of Object.entries(V)){if(!w.startsWith("@ebowwa/"))continue;let A=y.get(w),R=x.replace(/^[\^~]/,"");if(A){if(R===A)console.log(` ${w}: local=${R}, vps=${A} (in sync)`);else if(R>A)console.log(` ${w}: local=${R}, vps=${A} (VPS behind)`);else console.log(` ${w}: local=${R}, vps=${A} (local behind)`);y.delete(w)}else console.log(` ${w}: local=${R}, vps=not installed`)}for(let[w,x]of y)console.log(` ${w}: local=not in package.json, vps=${x}`)}else if(Q.length===0)console.log(" No packages installed on VPS");else for(let H of Q){let K=H.distSizeBytes?` (${(H.distSizeBytes/1024).toFixed(1)} KB)`:"";console.log(` ${H.packageName}@${H.version}${K}`)}}catch(q){console.error("Failed to get sync status:",q),process.exit(1)}finally{await J()}}async function R0($){console.log(`Running vulnerability scan...
13
+ `);try{let W=await(await U()).audit();if(W.length===0){console.log("No vulnerabilities found.");return}console.log(`Found ${W.length} vulnerability(es):
14
+ `);for(let X of W)console.log(`[${X.severity.toUpperCase()}] ${X.packageName}`),console.log(` Vulnerability: ${X.vulnerability}`),console.log(` Description: ${X.description}`),console.log("")}catch(Y){console.error("Audit failed:",Y),process.exit(1)}finally{await J()}}async function J1($){await R0($)}async function K1($){console.log(`Bundle sizes:
15
+ `);try{let W=await(await U()).getBundleSizes();if(W.length===0){console.log(" No packages installed");return}console.log(" Package | Version | Dist Size"),console.log(" --------------------------------|----------|-----------");for(let X of W){let Z=X.packageName.padEnd(32),q=X.version.padEnd(9),Q=(X.distSizeBytes/1024).toFixed(1)+" KB",H=X.fileCount?` (${X.fileCount} files)`:"";console.log(` ${Z} | ${q} | ${Q}${H}`)}}catch(Y){console.error("Failed to get bundle sizes:",Y),process.exit(1)}finally{await J()}}async function w1($){if($.length===0)console.error("Usage: pkg-ops versions <package>"),process.exit(1);let Y=$[0];if(!T(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);try{let X=await(await U()).listVersions(Y);if(await J(),X.length===0){console.log(`No versions of ${Y} installed.`);return}console.log(`Installed versions for ${Y}:
16
+ `);let Z=[...X].sort((q,Q)=>Q.installedAt.localeCompare(q.installedAt));for(let q of Z){let Q=q.active?" [ACTIVE]":"",H=q.distSizeBytes?` (${(q.distSizeBytes/1024).toFixed(1)} KB)`:"",K=new Date(q.installedAt).toLocaleString();if(console.log(` ${q.version}${Q}${H}`),console.log(` Installed: ${K}`),q.fileCount)console.log(` Files: ${q.fileCount}`)}console.log(`
17
+ Total: ${X.length} version(s)`)}catch(W){console.error("Failed to list versions:",W),process.exit(1)}finally{await J()}}async function E1($){if($.length===0)console.error("Usage: pkg-ops switch <package>@<version>"),process.exit(1);let Y=$[0],{name:W,version:X}=D(Y);if(!T(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);if(!X||X==="latest")console.error("Error: Must specify a version to switch to (e.g., @ebowwa/stack@0.7.12)"),process.exit(1);console.log(`Switching ${W} to version ${X}...`);try{let q=await(await U()).switchVersion(W,X);if(q.success){console.log(`Switched ${W} from ${q.fromVersion} to ${q.toVersion}`);let Q=_(),H=O(W);if(H?.service){if((await Q.status(H.service)).active)await Q.restart(H.service),console.log(` Service ${H.service} restarted`)}}else console.error(`Switch failed: ${q.message}`),process.exit(1)}catch(Z){console.error("Switch failed:",Z),process.exit(1)}finally{await J()}}async function U1($){if($.length===0)console.error("Usage: pkg-ops prune <package> [--keep N]"),process.exit(1);let Y=$[0],W=$.indexOf("--keep"),X=W>=0&&$[W+1]?parseInt($[W+1],10):2;if(!T(Y))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);console.log(`Pruning ${Y}, keeping ${X} most recent version(s)...`);try{let q=await(await U()).pruneVersions(Y,X);if(await J(),q.success)if(q.removedVersions.length===0)console.log(`No versions to remove (only ${q.keptVersions.length} installed).`);else{console.log(`Removed ${q.removedVersions.length} version(s):`);for(let Q of q.removedVersions)console.log(` - ${Q}`);console.log(`Freed: ${(q.freedBytes/1024).toFixed(1)} KB`),console.log(`Kept: ${q.keptVersions.join(", ")}`)}else console.error(`Prune failed: ${q.message}`),process.exit(1)}catch(Z){console.error("Prune failed:",Z),process.exit(1)}finally{await J()}}async function _1($){if($.length===0)console.error("Usage: pkg-ops remove-version <package>@<version>"),process.exit(1);let Y=$[0],{name:W,version:X}=D(Y);if(!T(W))console.error("Invalid package name. Only @ebowwa/* packages are supported."),process.exit(1);if(!X||X==="latest")console.error("Error: Must specify a version to remove (e.g., @ebowwa/stack@0.7.12)"),process.exit(1);if(O(W)?.version===X)console.error(`Error: Cannot remove active version ${X}. Switch to another version first.`),process.exit(1);console.log(`Removing ${W}@${X}...`);try{let Q=await(await U()).removeVersion(W,X);if(await J(),Q.success)console.log(`Removed ${W}@${X}`);else console.error(`Remove failed: ${Q.message}`),process.exit(1)}catch(q){console.error("Remove failed:",q),process.exit(1)}finally{await J()}}async function O1($){try{let W=await(await U()).getMultiVersionPackages();if(await J(),W.length===0){console.log("No packages with multiple versions installed.");return}console.log(`Packages with multiple versions:
18
+ `);for(let X of W)console.log(` ${X.packageName}:`),console.log(` Active: ${X.activeVersion}`),console.log(` Total: ${X.totalVersions} version(s)`),console.log(` Versions: ${X.versions.join(", ")}`),console.log("")}catch(Y){console.error("Failed to list multi-version packages:",Y),process.exit(1)}finally{await J()}}var T1=[{name:"install",description:"Install an @ebowwa/* package",usage:"pkg-ops install <package>[@version]",handler:Y1},{name:"update",description:"Update a package to latest version",usage:"pkg-ops update <package>",handler:$1},{name:"update-all",description:"Update all managed packages",usage:"pkg-ops update-all",handler:W1},{name:"list",description:"List installed packages",usage:"pkg-ops list",handler:X1},{name:"rollback",description:"Rollback a package to previous version",usage:"pkg-ops rollback <package>",handler:Z1},{name:"versions",description:"List all installed versions of a package",usage:"pkg-ops versions <package>",handler:w1},{name:"switch",description:"Switch to a specific installed version",usage:"pkg-ops switch <package>@<version>",handler:E1},{name:"prune",description:"Remove old versions, keeping N most recent",usage:"pkg-ops prune <package> [--keep N]",handler:U1},{name:"remove-version",description:"Remove a specific version",usage:"pkg-ops remove-version <package>@<version>",handler:_1},{name:"multi",description:"List packages with multiple versions",usage:"pkg-ops multi",handler:O1},{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:J0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:K0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:w0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:E0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:U0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:_0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:O0},{name:"health",description:"Check health of all services",usage:"pkg-ops health [service]",handler:q1},{name:"config",description:"Show configuration",usage:"pkg-ops config show",handler:T0},{name:"set-config",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:A0},{name:"verify",description:"Verify package integrity",usage:"pkg-ops verify <package>",handler:Q1},{name:"sync-status",description:"Show local vs VPS version sync",usage:"pkg-ops sync-status [--local-path path]",handler:H1},{name:"audit",description:"Check for vulnerabilities",usage:"pkg-ops audit",handler:R0},{name:"scan",description:"Alias for audit",usage:"pkg-ops scan",handler:J1},{name:"sizes",description:"Show bundle sizes",usage:"pkg-ops sizes",handler:K1}],A1=[{name:"start",description:"Start a systemd service",usage:"pkg-ops service start <name>",handler:J0},{name:"stop",description:"Stop a systemd service",usage:"pkg-ops service stop <name>",handler:K0},{name:"restart",description:"Restart a systemd service",usage:"pkg-ops service restart <name>",handler:w0},{name:"status",description:"Get service status",usage:"pkg-ops service status <name>",handler:E0},{name:"logs",description:"View service logs",usage:"pkg-ops service logs <name> [--lines N]",handler:U0},{name:"enable",description:"Enable service on boot",usage:"pkg-ops service enable <name>",handler:_0},{name:"disable",description:"Disable service from boot",usage:"pkg-ops service disable <name>",handler:O0}],R1=[{name:"show",description:"Show configuration",usage:"pkg-ops config show",handler:T0},{name:"set",description:"Set a config value",usage:"pkg-ops config set <package> <key> <value>",handler:A0}];function L1(){console.log(`
16
19
  PkgOps - Package operations CLI for VPS
17
20
 
18
21
  Usage:
@@ -25,6 +28,13 @@ Package Management:
25
28
  list List installed packages
26
29
  rollback <package> Rollback a package to previous version
27
30
 
31
+ Multi-Version Management:
32
+ versions <package> List all installed versions
33
+ switch <package>@<version> Switch to a specific version
34
+ prune <package> [--keep N] Remove old versions (default: keep 2)
35
+ remove-version <pkg>@<ver> Remove a specific version
36
+ multi List packages with multiple versions
37
+
28
38
  Service Management:
29
39
  service start <name> Start a systemd service
30
40
  service stop <name> Stop a systemd service
@@ -59,7 +69,7 @@ Examples:
59
69
  pkg-ops sync-status --local-path ./package.json
60
70
  pkg-ops verify @ebowwa/stack
61
71
  pkg-ops audit
62
- `)}async function X1(){let $=process.argv.slice(2);if($.length===0||$[0]==="--help"||$[0]==="-h")W1(),process.exit(0);if($[0]==="--version"||$[0]==="-v"){let Z=L();console.log(`pkg-ops ${Z.packages?.["@ebowwa/pkg-ops"]?.version??"0.1.0"}`),process.exit(0)}let Y=$[0],W=$.slice(1);if(Y==="service"){if(W.length===0)console.error("Missing service subcommand"),console.error("Usage: pkg-ops service <start|stop|restart|status|logs|enable|disable> <name>"),process.exit(1);let Z=W[0],q=Y1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown service subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}if(Y==="config"){if(W.length===0)console.error("Missing config subcommand"),console.error("Usage: pkg-ops config <show|set> [args...]"),process.exit(1);let Z=W[0],q=$1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown config subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}let X=e0.find((Z)=>Z.name===Y);if(!X)console.error(`Unknown command: ${Y}`),console.error("Run 'pkg-ops --help' for usage"),process.exit(1);await X.handler(W)}X1().catch(($)=>{console.error("Fatal error:",$),process.exit(1)});
72
+ `)}async function F1(){let $=process.argv.slice(2);if($.length===0||$[0]==="--help"||$[0]==="-h")L1(),process.exit(0);if($[0]==="--version"||$[0]==="-v"){let Z=E();console.log(`pkg-ops ${Z.packages?.["@ebowwa/pkg-ops"]?.version??"0.1.0"}`),process.exit(0)}let Y=$[0],W=$.slice(1);if(Y==="service"){if(W.length===0)console.error("Missing service subcommand"),console.error("Usage: pkg-ops service <start|stop|restart|status|logs|enable|disable> <name>"),process.exit(1);let Z=W[0],q=A1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown service subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}if(Y==="config"){if(W.length===0)console.error("Missing config subcommand"),console.error("Usage: pkg-ops config <show|set> [args...]"),process.exit(1);let Z=W[0],q=R1.find((Q)=>Q.name===Z);if(!q)console.error(`Unknown config subcommand: ${Z}`),process.exit(1);await q.handler(W.slice(1));return}let X=T1.find((Z)=>Z.name===Y);if(!X)console.error(`Unknown command: ${Y}`),console.error("Run 'pkg-ops --help' for usage"),process.exit(1);await X.handler(W)}if(__require.main==__require.module)F1().catch(($)=>{console.error("Fatal error:",$),process.exit(1)});export{M as updatePackageConfig,s0 as stopHealthServer,J as stopBridge,r0 as startHealthServer,U as startBridge,z0 as setActiveVersion,b as saveConfig,S0 as removePackageVersion,b0 as removePackageConfig,D as parsePackageSpec,E as loadConfig,d as listManagedPackages,M0 as isVersionInstalled,T as isValidPackageName,C0 as getVersionCount,_ as getServiceManager,h0 as getPackagesWithMultipleVersions,O as getPackageConfig,G0 as getInstalledVersions,r as getHealthServer,S as getConfigPath,Q0 as getBridge,D0 as getActiveVersion,a as ensureConfigDir,P0 as addPackageVersion,l as ServiceManager,c as RustBridge,n as HealthServer};
63
73
 
64
- //# debugId=2B766C7AE2D2DDC864756E2164756E21
74
+ //# debugId=C2965CBF167A76D764756E2164756E21
65
75
  //# sourceMappingURL=index.js.map