@burdenoff/vibe-agent 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/{app-6mmbmske.js → app-sm6n9xst.js} +13 -14
  2. package/dist/{app-6mmbmske.js.map → app-sm6n9xst.js.map} +3 -3
  3. package/dist/cli.js +28 -27
  4. package/dist/cli.js.map +5 -5
  5. package/dist/{index-41m1exz7.js → index-3rjnbp97.js} +3 -4
  6. package/dist/index-3rjnbp97.js.map +13 -0
  7. package/dist/{index-q4ytrfx7.js → index-6vry08rz.js} +4 -5
  8. package/dist/index-6vry08rz.js.map +13 -0
  9. package/dist/{index-9tgyd3ep.js → index-b1eq3qvs.js} +9 -7
  10. package/dist/{index-9tgyd3ep.js.map → index-b1eq3qvs.js.map} +3 -3
  11. package/dist/{index-wdtxbebz.js → index-fm6gqenc.js} +3 -4
  12. package/dist/index-fm6gqenc.js.map +13 -0
  13. package/dist/{index-3v78e2cn.js → index-s7ff1fj1.js} +88 -46
  14. package/dist/index-s7ff1fj1.js.map +11 -0
  15. package/dist/{index-xn4tarcd.js → index-t4qgjy5w.js} +4 -4
  16. package/dist/{index-qthbtg9n.js → index-wmvkjcjj.js} +4 -5
  17. package/dist/index-wmvkjcjj.js.map +13 -0
  18. package/dist/index.js +2 -2
  19. package/dist/{package-ywexp6sg.js → package-04nkt49b.js} +5 -3
  20. package/dist/{package-ywexp6sg.js.map → package-04nkt49b.js.map} +1 -1
  21. package/dist/{plugin-system-v7a7xnhk.js → plugin-system-7r9mb1tb.js} +17 -13
  22. package/dist/plugin-system-7r9mb1tb.js.map +10 -0
  23. package/package.json +3 -1
  24. package/dist/index-3v78e2cn.js.map +0 -11
  25. package/dist/index-41m1exz7.js.map +0 -13
  26. package/dist/index-q4ytrfx7.js.map +0 -13
  27. package/dist/index-qthbtg9n.js.map +0 -13
  28. package/dist/index-wdtxbebz.js.map +0 -13
  29. package/dist/plugin-system-v7a7xnhk.js.map +0 -10
  30. /package/dist/{index-xn4tarcd.js.map → index-t4qgjy5w.js.map} +0 -0
@@ -4,16 +4,30 @@ import {
4
4
  } from "./index-88ym10cs.js";
5
5
 
6
6
  // src/services/bootstrap.service.ts
7
- import { execSync } from "child_process";
8
7
  import os from "os";
9
8
  function checkCommand(cmd) {
10
9
  try {
11
- const version = execSync(`${cmd} --version 2>&1 || ${cmd} -v 2>&1`, {
10
+ const result = Bun.spawnSync([cmd, "--version"], {
12
11
  timeout: 5000,
13
- stdio: "pipe"
14
- }).toString().trim().split(`
12
+ stdout: "pipe",
13
+ stderr: "pipe"
14
+ });
15
+ if (result.exitCode === 0) {
16
+ const version = result.stdout.toString().trim().split(`
17
+ `)[0];
18
+ return { installed: true, version };
19
+ }
20
+ const result2 = Bun.spawnSync([cmd, "-v"], {
21
+ timeout: 5000,
22
+ stdout: "pipe",
23
+ stderr: "pipe"
24
+ });
25
+ if (result2.exitCode === 0) {
26
+ const version = result2.stdout.toString().trim().split(`
15
27
  `)[0];
16
- return { installed: true, version };
28
+ return { installed: true, version };
29
+ }
30
+ return { installed: false };
17
31
  } catch {
18
32
  return { installed: false };
19
33
  }
@@ -83,15 +97,27 @@ async function installDependencies(deps) {
83
97
  }
84
98
  async function installTmux(platform) {
85
99
  if (platform === "darwin") {
86
- execSync("brew install tmux", { timeout: 120000, stdio: "pipe" });
100
+ const r = Bun.spawnSync(["brew", "install", "tmux"], {
101
+ timeout: 120000,
102
+ stdout: "pipe",
103
+ stderr: "pipe"
104
+ });
105
+ if (r.exitCode !== 0)
106
+ throw new Error(r.stderr.toString());
87
107
  } else if (platform === "linux") {
88
- try {
89
- execSync("sudo apt-get install -y tmux", {
108
+ const apt = Bun.spawnSync(["sudo", "apt-get", "install", "-y", "tmux"], {
109
+ timeout: 120000,
110
+ stdout: "pipe",
111
+ stderr: "pipe"
112
+ });
113
+ if (apt.exitCode !== 0) {
114
+ const yum = Bun.spawnSync(["sudo", "yum", "install", "-y", "tmux"], {
90
115
  timeout: 120000,
91
- stdio: "pipe"
116
+ stdout: "pipe",
117
+ stderr: "pipe"
92
118
  });
93
- } catch {
94
- execSync("sudo yum install -y tmux", { timeout: 120000, stdio: "pipe" });
119
+ if (yum.exitCode !== 0)
120
+ throw new Error(yum.stderr.toString());
95
121
  }
96
122
  } else {
97
123
  throw new Error(`Unsupported platform for tmux: ${platform}`);
@@ -99,16 +125,24 @@ async function installTmux(platform) {
99
125
  }
100
126
  async function installTtyd(platform) {
101
127
  if (platform === "darwin") {
102
- execSync("brew install ttyd", { timeout: 120000, stdio: "pipe" });
128
+ const r = Bun.spawnSync(["brew", "install", "ttyd"], {
129
+ timeout: 120000,
130
+ stdout: "pipe",
131
+ stderr: "pipe"
132
+ });
133
+ if (r.exitCode !== 0)
134
+ throw new Error(r.stderr.toString());
103
135
  } else if (platform === "linux") {
104
- try {
105
- execSync("sudo snap install ttyd --classic", {
106
- timeout: 120000,
107
- stdio: "pipe"
108
- });
109
- } catch {
136
+ const snap = Bun.spawnSync(["sudo", "snap", "install", "ttyd", "--classic"], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
137
+ if (snap.exitCode !== 0) {
110
138
  const arch = os.arch() === "x64" ? "x86_64" : os.arch();
111
- execSync(`curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`, { timeout: 120000, stdio: "pipe" });
139
+ const curl = Bun.spawnSync([
140
+ "sh",
141
+ "-c",
142
+ `curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`
143
+ ], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
144
+ if (curl.exitCode !== 0)
145
+ throw new Error(curl.stderr.toString());
112
146
  }
113
147
  } else {
114
148
  throw new Error(`Unsupported platform for ttyd: ${platform}`);
@@ -116,7 +150,13 @@ async function installTtyd(platform) {
116
150
  }
117
151
  async function installCloudflared(platform) {
118
152
  if (platform === "darwin") {
119
- execSync("brew install cloudflared", { timeout: 120000, stdio: "pipe" });
153
+ const r = Bun.spawnSync(["brew", "install", "cloudflared"], {
154
+ timeout: 120000,
155
+ stdout: "pipe",
156
+ stderr: "pipe"
157
+ });
158
+ if (r.exitCode !== 0)
159
+ throw new Error(r.stderr.toString());
120
160
  } else if (platform === "linux") {
121
161
  const arch = os.arch();
122
162
  let archStr = "amd64";
@@ -124,15 +164,19 @@ async function installCloudflared(platform) {
124
164
  archStr = "arm64";
125
165
  else if (arch === "arm")
126
166
  archStr = "arm";
127
- execSync(`curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`, { timeout: 120000, stdio: "pipe" });
167
+ const r = Bun.spawnSync([
168
+ "sh",
169
+ "-c",
170
+ `curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`
171
+ ], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
172
+ if (r.exitCode !== 0)
173
+ throw new Error(r.stderr.toString());
128
174
  } else {
129
175
  throw new Error(`Unsupported platform for cloudflared: ${platform}`);
130
176
  }
131
177
  }
132
178
 
133
179
  // src/services/service-manager.ts
134
- import { spawn } from "child_process";
135
- import { promisify } from "util";
136
180
  import {
137
181
  existsSync,
138
182
  readFileSync,
@@ -141,13 +185,8 @@ import {
141
185
  openSync,
142
186
  closeSync
143
187
  } from "fs";
144
- import { join, dirname } from "path";
145
- import { fileURLToPath } from "url";
188
+ import { join } from "path";
146
189
  import { homedir } from "os";
147
- import { exec } from "child_process";
148
- var execAsync = promisify(exec);
149
- var __filename2 = fileURLToPath(import.meta.url);
150
- var __dirname2 = dirname(__filename2);
151
190
 
152
191
  class ServiceManager {
153
192
  registryPath;
@@ -167,10 +206,11 @@ class ServiceManager {
167
206
  }
168
207
  const logFile = join(this.logsDir, `${config.name}.log`);
169
208
  const logFd = openSync(logFile, "a");
170
- const indexPath = join(__dirname2, "..", "index.js");
171
- const child = spawn("bun", ["run", indexPath], {
172
- detached: true,
173
- stdio: ["ignore", logFd, logFd],
209
+ const indexPath = join(import.meta.dir, "..", "index.js");
210
+ const child = Bun.spawn(["bun", "run", indexPath], {
211
+ stdin: "ignore",
212
+ stdout: logFd,
213
+ stderr: logFd,
174
214
  env: {
175
215
  ...process.env,
176
216
  PORT: config.port.toString(),
@@ -179,7 +219,6 @@ class ServiceManager {
179
219
  }
180
220
  });
181
221
  closeSync(logFd);
182
- child.unref();
183
222
  await new Promise((resolve) => setTimeout(resolve, 2000));
184
223
  const isRunning = await this.isProcessRunning(child.pid);
185
224
  if (!isRunning) {
@@ -250,22 +289,25 @@ class ServiceManager {
250
289
  return;
251
290
  }
252
291
  if (options.follow) {
253
- const tail = spawn("tail", [
254
- "-f",
255
- "-n",
256
- options.tail.toString(),
257
- logFile
258
- ]);
259
- tail.stdout?.on("data", (data) => process.stdout.write(data));
260
- tail.stderr?.on("data", (data) => process.stderr.write(data));
292
+ const tail = Bun.spawn(["tail", "-f", "-n", options.tail.toString(), logFile], { stdout: "pipe", stderr: "pipe" });
293
+ (async () => {
294
+ for await (const chunk of tail.stdout) {
295
+ process.stdout.write(chunk);
296
+ }
297
+ })();
298
+ (async () => {
299
+ for await (const chunk of tail.stderr) {
300
+ process.stderr.write(chunk);
301
+ }
302
+ })();
261
303
  process.on("SIGINT", () => {
262
304
  tail.kill();
263
305
  process.exit(0);
264
306
  });
265
307
  } else {
266
308
  try {
267
- const { stdout } = await execAsync(`tail -n ${options.tail} "${logFile}"`);
268
- console.log(stdout);
309
+ const proc = Bun.spawnSync(["tail", "-n", options.tail.toString(), logFile], { stdout: "pipe", stderr: "pipe" });
310
+ console.log(proc.stdout.toString());
269
311
  } catch (err) {
270
312
  console.error("Failed to read logs:", err);
271
313
  }
@@ -369,5 +411,5 @@ class ServiceManager {
369
411
 
370
412
  export { checkDependencies, installDependencies, ServiceManager };
371
413
 
372
- //# debugId=1F2B497AC857BCC064756E2164756E21
373
- //# sourceMappingURL=index-3v78e2cn.js.map
414
+ //# debugId=6E0629A41BAEEB3564756E2164756E21
415
+ //# sourceMappingURL=index-s7ff1fj1.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/services/bootstrap.service.ts", "../src/services/service-manager.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Bootstrap Service\n *\n * Handles dependency checking and auto-installation for the vibe agent.\n * Checks for required system tools and optionally installs them.\n *\n * Required prerequisites:\n * - bun (runtime - already present if running this code)\n * - tmux (installed via session-tmux plugin, but checked here for setup)\n * - ttyd (installed via session-tmux plugin, but checked here for setup)\n * - cloudflared (installed via tunnel-cloudflare plugin, but checked here for setup)\n */\n\nimport os from \"node:os\";\n\nimport { logger } from \"./logger.js\";\n\n// ── Types ────────────────────────────────────────────────────────────────\n\nexport interface DependencyCheck {\n name: string;\n installed: boolean;\n version?: string;\n required: boolean;\n category: \"runtime\" | \"session\" | \"tunnel\" | \"tool\";\n}\n\nexport interface SetupResult {\n success: boolean;\n installed: string[];\n failed: string[];\n skipped: string[];\n}\n\n// ── Check Functions ─────────────────────────────────────────────────────\n\nfunction checkCommand(cmd: string): { installed: boolean; version?: string } {\n try {\n const result = Bun.spawnSync([cmd, \"--version\"], {\n timeout: 5000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (result.exitCode === 0) {\n const version = result.stdout.toString().trim().split(\"\\n\")[0];\n return { installed: true, version };\n }\n // Try -v fallback\n const result2 = Bun.spawnSync([cmd, \"-v\"], {\n timeout: 5000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (result2.exitCode === 0) {\n const version = result2.stdout.toString().trim().split(\"\\n\")[0];\n return { installed: true, version };\n }\n return { installed: false };\n } catch {\n return { installed: false };\n }\n}\n\n/**\n * Check all dependencies and return their status.\n */\nexport function checkDependencies(): DependencyCheck[] {\n const deps: Array<{\n name: string;\n cmd: string;\n required: boolean;\n category: DependencyCheck[\"category\"];\n }> = [\n { name: \"bun\", cmd: \"bun\", required: true, category: \"runtime\" },\n { name: \"tmux\", cmd: \"tmux\", required: false, category: \"session\" },\n { name: \"ttyd\", cmd: \"ttyd\", required: false, category: \"session\" },\n {\n name: \"cloudflared\",\n cmd: \"cloudflared\",\n required: false,\n category: \"tunnel\",\n },\n ];\n\n return deps.map((dep) => {\n const { installed, version } = checkCommand(dep.cmd);\n return {\n name: dep.name,\n installed,\n version,\n required: dep.required,\n category: dep.category,\n };\n });\n}\n\n/**\n * Install missing dependencies.\n */\nexport async function installDependencies(\n deps?: string[],\n): Promise<SetupResult> {\n const platform = os.platform();\n const result: SetupResult = {\n success: true,\n installed: [],\n failed: [],\n skipped: [],\n };\n\n const checks = checkDependencies();\n const toInstall = deps\n ? checks.filter((d) => deps.includes(d.name) && !d.installed)\n : checks.filter((d) => !d.installed);\n\n for (const dep of toInstall) {\n try {\n logger.info(\"bootstrap\", `Installing ${dep.name}...`);\n\n if (dep.name === \"tmux\") {\n await installTmux(platform);\n } else if (dep.name === \"ttyd\") {\n await installTtyd(platform);\n } else if (dep.name === \"cloudflared\") {\n await installCloudflared(platform);\n } else {\n result.skipped.push(dep.name);\n continue;\n }\n\n // Verify installation\n const check = checkCommand(dep.name);\n if (check.installed) {\n result.installed.push(dep.name);\n logger.info(\n \"bootstrap\",\n `Successfully installed ${dep.name}: ${check.version}`,\n );\n } else {\n result.failed.push(dep.name);\n result.success = false;\n logger.error(\n \"bootstrap\",\n `Failed to install ${dep.name}: command not found after install`,\n );\n }\n } catch (err) {\n result.failed.push(dep.name);\n result.success = false;\n logger.error(\"bootstrap\", `Failed to install ${dep.name}: ${err}`);\n }\n }\n\n return result;\n}\n\n// ── Platform-Specific Installers ────────────────────────────────────────\n\nasync function installTmux(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n const r = Bun.spawnSync([\"brew\", \"install\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else if (platform === \"linux\") {\n const apt = Bun.spawnSync([\"sudo\", \"apt-get\", \"install\", \"-y\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (apt.exitCode !== 0) {\n const yum = Bun.spawnSync([\"sudo\", \"yum\", \"install\", \"-y\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (yum.exitCode !== 0) throw new Error(yum.stderr.toString());\n }\n } else {\n throw new Error(`Unsupported platform for tmux: ${platform}`);\n }\n}\n\nasync function installTtyd(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n const r = Bun.spawnSync([\"brew\", \"install\", \"ttyd\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else if (platform === \"linux\") {\n const snap = Bun.spawnSync(\n [\"sudo\", \"snap\", \"install\", \"ttyd\", \"--classic\"],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (snap.exitCode !== 0) {\n // Try direct download\n const arch = os.arch() === \"x64\" ? \"x86_64\" : os.arch();\n const curl = Bun.spawnSync(\n [\n \"sh\",\n \"-c\",\n `curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`,\n ],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (curl.exitCode !== 0) throw new Error(curl.stderr.toString());\n }\n } else {\n throw new Error(`Unsupported platform for ttyd: ${platform}`);\n }\n}\n\nasync function installCloudflared(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n const r = Bun.spawnSync([\"brew\", \"install\", \"cloudflared\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else if (platform === \"linux\") {\n const arch = os.arch();\n let archStr = \"amd64\";\n if (arch === \"arm64\" || (arch as string) === \"aarch64\") archStr = \"arm64\";\n else if (arch === \"arm\") archStr = \"arm\";\n\n const r = Bun.spawnSync(\n [\n \"sh\",\n \"-c\",\n `curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`,\n ],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else {\n throw new Error(`Unsupported platform for cloudflared: ${platform}`);\n }\n}\n",
6
+ "/**\n * Service Manager\n *\n * Manages multiple agent instances as background daemon processes.\n * Handles start, stop, restart, kill, status, and log operations.\n *\n * Process registry persisted at ~/.vibecontrols/agents.json\n * Logs written to ~/.vibecontrols/logs/{name}.log\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n openSync,\n closeSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nimport type { AgentConfig } from \"./agent.service.js\";\n\nexport interface ProcessInfo {\n name: string;\n pid: number;\n port: number;\n config: AgentConfig;\n startTime: string;\n status: \"running\" | \"stopped\" | \"unknown\";\n}\n\nexport interface LogOptions {\n follow: boolean;\n tail: number;\n}\n\nexport class ServiceManager {\n private registryPath: string;\n private logsDir: string;\n\n constructor() {\n const configDir = join(homedir(), \".vibecontrols\");\n this.registryPath = join(configDir, \"agents.json\");\n this.logsDir = join(configDir, \"logs\");\n\n mkdirSync(configDir, { recursive: true });\n mkdirSync(this.logsDir, { recursive: true });\n }\n\n async startDaemon(config: AgentConfig): Promise<void> {\n // Check if already running\n const existing = await this.findProcessByName(config.name);\n if (existing && existing.status === \"running\") {\n console.log(\n `⚠️ Agent '${config.name}' is already running on port ${existing.port}`,\n );\n return;\n }\n\n // Create log file FD for direct redirect\n const logFile = join(this.logsDir, `${config.name}.log`);\n const logFd = openSync(logFile, \"a\");\n\n // Spawn the process using bun\n // index.js lives alongside this compiled file in dist/\n const indexPath = join(import.meta.dir, \"..\", \"index.js\");\n const child = Bun.spawn([\"bun\", \"run\", indexPath], {\n stdin: \"ignore\",\n stdout: logFd,\n stderr: logFd,\n env: {\n ...process.env,\n PORT: config.port.toString(),\n DB_PATH: config.dbPath,\n NODE_ENV: \"production\",\n },\n });\n\n closeSync(logFd);\n\n // Wait for process to start\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n const isRunning = await this.isProcessRunning(child.pid);\n if (!isRunning) {\n throw new Error(`Failed to start agent '${config.name}'`);\n }\n\n await this.saveProcessInfo(config.name, child.pid, config);\n console.log(\n `🚀 Agent '${config.name}' started (PID: ${child.pid}, Port: ${config.port})`,\n );\n }\n\n async stop(name: string): Promise<void> {\n const agentProcess = await this.findProcessByName(name);\n if (!agentProcess || agentProcess.status !== \"running\") {\n console.log(`⚠️ Agent '${name}' is not running`);\n return;\n }\n\n try {\n process.kill(agentProcess.pid, \"SIGTERM\");\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n const stillRunning = await this.isProcessRunning(agentProcess.pid);\n if (stillRunning) {\n process.kill(agentProcess.pid, \"SIGKILL\");\n }\n\n await this.updateProcessStatus(name, \"stopped\");\n console.log(`✅ Agent '${name}' stopped`);\n } catch (err) {\n throw new Error(`Failed to stop agent '${name}': ${err}`, { cause: err });\n }\n }\n\n async restart(name: string, config: AgentConfig): Promise<void> {\n const existing = await this.findProcessByName(name);\n if (existing && existing.status === \"running\") {\n await this.stop(name);\n }\n await this.startDaemon(config);\n console.log(`🔄 Agent '${name}' restarted`);\n }\n\n async kill(name: string): Promise<void> {\n const agentProcess = await this.findProcessByName(name);\n if (!agentProcess || agentProcess.status !== \"running\") {\n console.log(`⚠️ Agent '${name}' is not running`);\n return;\n }\n\n await this.killProcessTree(agentProcess.pid);\n await this.updateProcessStatus(name, \"stopped\");\n console.log(`💀 Agent '${name}' killed`);\n }\n\n async getStatus(name: string): Promise<ProcessInfo | null> {\n return this.findProcessByName(name);\n }\n\n async getStatusAll(): Promise<ProcessInfo[]> {\n const registry = this.loadRegistry();\n const processes: ProcessInfo[] = [];\n\n for (const processInfo of registry) {\n const isRunning = await this.isProcessRunning(processInfo.pid);\n processes.push({\n ...processInfo,\n status: isRunning ? \"running\" : \"stopped\",\n });\n }\n\n return processes;\n }\n\n async listInstances(): Promise<ProcessInfo[]> {\n return this.getStatusAll();\n }\n\n async showLogs(name: string, options: LogOptions): Promise<void> {\n const logFile = join(this.logsDir, `${name}.log`);\n\n if (!existsSync(logFile)) {\n console.log(`No logs found for agent '${name}'`);\n return;\n }\n\n if (options.follow) {\n const tail = Bun.spawn(\n [\"tail\", \"-f\", \"-n\", options.tail.toString(), logFile],\n { stdout: \"pipe\", stderr: \"pipe\" },\n );\n\n // Pipe stdout and stderr to process\n (async () => {\n for await (const chunk of tail.stdout as ReadableStream) {\n process.stdout.write(chunk);\n }\n })();\n (async () => {\n for await (const chunk of tail.stderr as ReadableStream) {\n process.stderr.write(chunk);\n }\n })();\n\n process.on(\"SIGINT\", () => {\n tail.kill();\n process.exit(0);\n });\n } else {\n try {\n const proc = Bun.spawnSync(\n [\"tail\", \"-n\", options.tail.toString(), logFile],\n { stdout: \"pipe\", stderr: \"pipe\" },\n );\n console.log(proc.stdout.toString());\n } catch (err) {\n console.error(\"Failed to read logs:\", err);\n }\n }\n }\n\n async checkHealth(\n name: string,\n ): Promise<{ healthy: boolean; details: unknown }> {\n const proc = await this.findProcessByName(name);\n\n if (!proc || proc.status !== \"running\") {\n return { healthy: false, details: { error: \"Process not running\" } };\n }\n\n try {\n const response = await fetch(`http://localhost:${proc.port}/health`);\n const data = await response.json();\n return { healthy: response.ok, details: data };\n } catch (err) {\n return {\n healthy: false,\n details: {\n error: \"Health check failed\",\n message: (err as Error).message,\n },\n };\n }\n }\n\n async setConfig(key: string, value: string): Promise<void> {\n const configFile = join(homedir(), \".vibecontrols\", \"config.json\");\n let config: Record<string, unknown> = {};\n if (existsSync(configFile)) {\n config = JSON.parse(readFileSync(configFile, \"utf8\"));\n }\n config[key] = value;\n writeFileSync(configFile, JSON.stringify(config, null, 2));\n }\n\n async getConfig(key?: string): Promise<unknown> {\n const configFile = join(homedir(), \".vibecontrols\", \"config.json\");\n if (!existsSync(configFile)) return key ? undefined : {};\n const config = JSON.parse(readFileSync(configFile, \"utf8\"));\n return key ? config[key] : config;\n }\n\n // ── Private Helpers ───────────────────────────────────────────────\n\n private loadRegistry(): ProcessInfo[] {\n if (!existsSync(this.registryPath)) return [];\n try {\n return JSON.parse(readFileSync(this.registryPath, \"utf8\"));\n } catch {\n return [];\n }\n }\n\n private saveRegistry(processes: ProcessInfo[]): void {\n writeFileSync(this.registryPath, JSON.stringify(processes, null, 2));\n }\n\n private async saveProcessInfo(\n name: string,\n pid: number,\n config: AgentConfig,\n ): Promise<void> {\n const registry = this.loadRegistry();\n const filtered = registry.filter((p) => p.name !== name);\n filtered.push({\n name,\n pid,\n port: config.port,\n config,\n startTime: new Date().toISOString(),\n status: \"running\",\n });\n this.saveRegistry(filtered);\n }\n\n private async updateProcessStatus(\n name: string,\n status: \"running\" | \"stopped\" | \"unknown\",\n ): Promise<void> {\n const registry = this.loadRegistry();\n const proc = registry.find((p) => p.name === name);\n if (proc) {\n proc.status = status;\n this.saveRegistry(registry);\n }\n }\n\n private async findProcessByName(name: string): Promise<ProcessInfo | null> {\n const registry = this.loadRegistry();\n const proc = registry.find((p) => p.name === name);\n if (!proc) return null;\n const isRunning = await this.isProcessRunning(proc.pid);\n proc.status = isRunning ? \"running\" : \"stopped\";\n return proc;\n }\n\n private async isProcessRunning(pid: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n private async killProcessTree(pid: number): Promise<void> {\n try {\n // Kill process group\n process.kill(-pid, \"SIGKILL\");\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // Process already dead\n }\n }\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "6E0629A41BAEEB3564756E2164756E21",
10
+ "names": []
11
+ }
@@ -160,7 +160,7 @@ function register(program) {
160
160
  } catch {
161
161
  warn("Agent not reachable. Attempting local plugin registry...");
162
162
  try {
163
- const { PluginManager } = await import("./plugin-system-v7a7xnhk.js");
163
+ const { PluginManager } = await import("./plugin-system-7r9mb1tb.js");
164
164
  const pm = new PluginManager;
165
165
  plugins = pm.getPluginDetails() || [];
166
166
  } catch {
@@ -196,7 +196,7 @@ function register(program) {
196
196
  } catch {
197
197
  warn("Agent not reachable. Attempting local install...");
198
198
  try {
199
- const { PluginManager } = await import("./plugin-system-v7a7xnhk.js");
199
+ const { PluginManager } = await import("./plugin-system-7r9mb1tb.js");
200
200
  const pm = new PluginManager;
201
201
  await pm.install(packageName);
202
202
  success(`Plugin "${packageName}" installed locally.`);
@@ -219,7 +219,7 @@ function register(program) {
219
219
  } catch {
220
220
  warn("Agent not reachable. Attempting local removal...");
221
221
  try {
222
- const { PluginManager } = await import("./plugin-system-v7a7xnhk.js");
222
+ const { PluginManager } = await import("./plugin-system-7r9mb1tb.js");
223
223
  const pm = new PluginManager;
224
224
  await pm.remove(packageName);
225
225
  success(`Plugin "${packageName}" removed locally.`);
@@ -284,4 +284,4 @@ export {
284
284
  };
285
285
 
286
286
  //# debugId=6D591618982CB48A64756E2164756E21
287
- //# sourceMappingURL=index-xn4tarcd.js.map
287
+ //# sourceMappingURL=index-t4qgjy5w.js.map
@@ -22,7 +22,6 @@ import {
22
22
  import"./index-g8dczzvv.js";
23
23
 
24
24
  // src/plugins/notification/routes.ts
25
- import crypto from "crypto";
26
25
  function createRoutes(deps) {
27
26
  const { db } = deps;
28
27
  return new Elysia().get("/", ({ query }) => {
@@ -69,7 +68,7 @@ function createRoutes(deps) {
69
68
  }).post("/", ({ body, set }) => {
70
69
  try {
71
70
  const notification = db.createNotification({
72
- id: crypto.randomUUID(),
71
+ id: globalThis.crypto.randomUUID(),
73
72
  sessionName: body.sessionName,
74
73
  projectId: body.projectId,
75
74
  type: body.type || "info",
@@ -144,7 +143,7 @@ function createRoutes(deps) {
144
143
 
145
144
  Metadata: ${JSON.stringify(body.metadata, null, 2)}` : body.message;
146
145
  const notification = db.createNotification({
147
- id: crypto.randomUUID(),
146
+ id: globalThis.crypto.randomUUID(),
148
147
  sessionName: body.projectName,
149
148
  projectId: params.sessionId,
150
149
  type: mappedType,
@@ -298,5 +297,5 @@ export {
298
297
  vibePlugin
299
298
  };
300
299
 
301
- //# debugId=933C583CBD4F9A8B64756E2164756E21
302
- //# sourceMappingURL=index-qthbtg9n.js.map
300
+ //# debugId=AE9C4A672990742664756E2164756E21
301
+ //# sourceMappingURL=index-wmvkjcjj.js.map
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/plugins/notification/routes.ts", "../src/cli/commands/notify.cmd.ts", "../src/plugins/notification/commands.ts", "../src/plugins/notification/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Notification Plugin — Routes\n *\n * Notification management — CRUD, read/unread status, webhook endpoint.\n *\n * Endpoints (mounted by plugin system at /api/notifications):\n * GET / — List notifications (with filters)\n * GET /unread — Get unread notifications\n * GET /global — Get global notifications\n * GET /project/:projectId — Get notifications by project\n * PUT /read-all — Mark all as read\n * DELETE /clear/old — Clear old notifications\n * GET /:id — Get notification by ID\n * POST / — Create notification\n * PUT /:id/read — Mark as read\n * PUT /:id/unread — Mark as unread\n * DELETE /:id — Delete notification\n * POST /webhook/:sessionId — Webhook for external notifications\n */\n\nimport { Elysia, t } from \"elysia\";\n\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return (\n new Elysia()\n // List notifications (with optional filters)\n .get(\"/\", ({ query }) => {\n const q = query as Record<string, string>;\n\n if (q.status === \"unread\") {\n return { notifications: db.getUnreadNotifications() };\n }\n if (q.projectId !== undefined) {\n return { notifications: db.getNotificationsByProject(q.projectId) };\n }\n return { notifications: db.getAllNotifications() };\n })\n\n // Get unread notifications\n .get(\"/unread\", () => {\n const notifications = db.getUnreadNotifications();\n return { notifications, count: notifications.length };\n })\n\n // Get global notifications (not tied to a project)\n .get(\"/global\", () => {\n const notifications = db.getGlobalNotifications();\n return { notifications, count: notifications.length };\n })\n\n // Get notifications by project\n .get(\"/project/:projectId\", ({ params }) => {\n const notifications = db.getNotificationsByProject(params.projectId);\n return { notifications };\n })\n\n // Mark all as read — defined before /:id to avoid route conflict\n .put(\"/read-all\", ({ set }) => {\n try {\n const count = db.markAllNotificationsRead();\n return { success: true, markedCount: count };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to mark all notifications as read\",\n details: String(err),\n };\n }\n })\n\n // Clear old notifications — defined before /:id to avoid route conflict\n .delete(\"/clear/old\", ({ query }) => {\n const q = query as Record<string, string>;\n const days = q.days ? parseInt(q.days, 10) : 30;\n const count = db.clearOldNotifications(days);\n return { success: true, deletedCount: count };\n })\n\n // Get notification by ID\n .get(\"/:id\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n return { notification };\n })\n\n // Create notification\n .post(\n \"/\",\n ({ body, set }) => {\n try {\n const notification = db.createNotification({\n id: globalThis.crypto.randomUUID(),\n sessionName: body.sessionName,\n projectId: body.projectId,\n type: body.type || \"info\",\n title: body.title,\n message: body.message,\n status: \"unread\",\n });\n return { notification };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create notification\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n sessionName: t.Optional(t.String()),\n projectId: t.Optional(t.String()),\n type: t.Optional(\n t.Union([\n t.Literal(\"info\"),\n t.Literal(\"success\"),\n t.Literal(\"warning\"),\n t.Literal(\"error\"),\n ]),\n ),\n title: t.String(),\n message: t.String(),\n }),\n },\n )\n\n // Mark as read\n .put(\"/:id/read\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n db.updateNotificationStatus(params.id, \"read\");\n return { success: true };\n })\n\n // Mark as unread\n .put(\"/:id/unread\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n db.updateNotificationStatus(params.id, \"unread\");\n return { success: true };\n })\n\n // Delete notification\n .delete(\"/:id\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n\n try {\n db.deleteNotification(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to delete notification\",\n details: String(err),\n };\n }\n })\n\n // Webhook endpoint for external notifications\n .post(\n \"/webhook/:sessionId\",\n ({ params, body, set }) => {\n try {\n // Map type variants to valid DB types\n const typeMap: Record<\n string,\n \"info\" | \"success\" | \"warning\" | \"error\"\n > = {\n task_completed: \"success\",\n info: \"info\",\n success: \"success\",\n warning: \"warning\",\n error: \"error\",\n };\n const mappedType = typeMap[body.type || \"info\"] || \"info\";\n\n const message = body.metadata\n ? `${body.message}\\n\\nMetadata: ${JSON.stringify(body.metadata, null, 2)}`\n : body.message;\n\n const notification = db.createNotification({\n id: globalThis.crypto.randomUUID(),\n sessionName: body.projectName,\n projectId: params.sessionId,\n type: mappedType,\n title: body.title,\n message,\n status: \"unread\",\n });\n\n return {\n notification,\n webhook: true,\n originalType: body.type || \"info\",\n mappedType,\n };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create webhook notification\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n type: t.Optional(t.String()),\n title: t.String(),\n message: t.String(),\n metadata: t.Optional(t.Record(t.String(), t.Unknown())),\n projectName: t.Optional(t.String()),\n }),\n },\n )\n );\n}\n",
6
+ "import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n blank,\n formatNotificationType,\n timeAgo,\n shortId,\n colors,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program.command(\"notify\").description(\"Manage notifications\");\n\n // notify list\n cmd\n .command(\"list\")\n .description(\"List notifications\")\n .option(\"--unread\", \"Show only unread notifications\")\n .option(\"--project <id>\", \"Filter by project ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const params = new URLSearchParams();\n if (options.unread) params.set(\"unread\", \"true\");\n if (options.project) params.set(\"project\", options.project);\n const query = params.toString();\n const endpoint = query\n ? `/api/notifications?${query}`\n : \"/api/notifications\";\n const data = await apiGet<{ notifications: any[] }>(url, endpoint);\n const notifications = data.notifications || [];\n if (!notifications || notifications.length === 0) {\n info(\"No notifications found.\");\n return;\n }\n header(\"Notifications\");\n blank();\n for (const n of notifications) {\n const icon = formatNotificationType(n.type);\n const time = n.createdAt ? colors.dim(timeAgo(n.createdAt)) : \"\";\n const title = colors.bold(n.title || \"Untitled\");\n const id = colors.dim(`[${shortId(n.id)}]`);\n console.log(` ${icon} ${title} ${id} ${time}`);\n if (n.message) {\n console.log(` ${n.message}`);\n }\n blank();\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify create\n cmd\n .command(\"create\")\n .description(\"Create a notification\")\n .requiredOption(\"--title <title>\", \"Notification title\")\n .requiredOption(\"--message <msg>\", \"Notification message\")\n .option(\"--type <type>\", \"Notification type\", \"info\")\n .option(\"--project <id>\", \"Project ID\")\n .option(\"--session <name>\", \"Session name\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {\n title: options.title,\n message: options.message,\n type: options.type,\n };\n if (options.project) body.project = options.project;\n if (options.session) body.session = options.session;\n const result = await apiPost<any>(url, \"/api/notifications\", body);\n success(`Notification created: ${shortId(result?.id)}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify delete\n cmd\n .command(\"delete\")\n .description(\"Delete a notification\")\n .requiredOption(\"-i, --id <id>\", \"Notification ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, `/api/notifications/${options.id}`);\n success(`Notification ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify read-all\n cmd\n .command(\"read-all\")\n .description(\"Mark all notifications as read\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiPut<any>(url, \"/api/notifications/read-all\", {});\n success(\"All notifications marked as read.\");\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify clear-old\n cmd\n .command(\"clear-old\")\n .description(\"Clear old notifications\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, \"/api/notifications/clear/old\");\n success(\"Old notifications cleared.\");\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify webhook\n cmd\n .command(\"webhook\")\n .description(\"Send a webhook notification to a session\")\n .requiredOption(\"--session <sessionId>\", \"Target session ID\")\n .option(\"--title <title>\", \"Notification title\")\n .option(\"--message <msg>\", \"Notification message\")\n .option(\"--type <type>\", \"Notification type\", \"info\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.title) body.title = options.title;\n if (options.message) body.message = options.message;\n if (options.type) body.type = options.type;\n await apiPost<any>(\n url,\n `/api/notifications/webhook/${options.session}`,\n body,\n );\n success(\n `Webhook notification sent to session ${shortId(options.session)}.`,\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
7
+ "import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerNotify } from \"../../cli/commands/notify.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerNotify(program);\n}\n",
8
+ "import type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"notification\",\n version: \"2.2.0\",\n description: \"Notification management — CRUD, read/unread status, webhooks\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"notify\",\n apiPrefix: \"/api/notifications\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "AE9C4A672990742664756E2164756E21",
12
+ "names": []
13
+ }
package/dist/index.js CHANGED
@@ -9,8 +9,8 @@ import"./index-wr0mkm57.js";
9
9
  import"./index-g8dczzvv.js";
10
10
  import {
11
11
  createApp
12
- } from "./app-6mmbmske.js";
13
- import"./plugin-system-v7a7xnhk.js";
12
+ } from "./app-sm6n9xst.js";
13
+ import"./plugin-system-7r9mb1tb.js";
14
14
 
15
15
  // src/index.ts
16
16
  if (typeof Bun === "undefined") {
@@ -3,7 +3,7 @@ import"./index-g8dczzvv.js";
3
3
 
4
4
  // package.json
5
5
  var name = "@burdenoff/vibe-agent";
6
- var version = "2.2.0";
6
+ var version = "2.3.0";
7
7
  var main = "./dist/index.js";
8
8
  var type = "module";
9
9
  var bin = {
@@ -47,6 +47,8 @@ var author = {
47
47
  var license = "SEE LICENSE IN LICENSE";
48
48
  var description = "VibeControls Agent CLI - Remote development environment management with terminal multiplexing, tunnels, and extensible plugins. Powered by Bun + Elysia.";
49
49
  var dependencies = {
50
+ "@burdenoff/vibe-plugin-ai": "2.0.0",
51
+ "@burdenoff/vibe-plugin-ssh": "2.0.0",
50
52
  "@elysiajs/cors": "^1.3.1",
51
53
  commander: "^14.0.3",
52
54
  elysia: "^1.3.2"
@@ -132,5 +134,5 @@ export {
132
134
  author
133
135
  };
134
136
 
135
- //# debugId=FE5C6CE1D82E16A864756E2164756E21
136
- //# sourceMappingURL=package-ywexp6sg.js.map
137
+ //# debugId=5FB86CA3CE7847C964756E2164756E21
138
+ //# sourceMappingURL=package-04nkt49b.js.map
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "FE5C6CE1D82E16A864756E2164756E21",
7
+ "debugId": "5FB86CA3CE7847C964756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -11,7 +11,6 @@ import {
11
11
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
12
12
  import { join } from "path";
13
13
  import os from "os";
14
- import { execSync } from "child_process";
15
14
  var CORE_PLUGIN_NAMES = [
16
15
  "agent",
17
16
  "session",
@@ -65,17 +64,17 @@ class PluginManager {
65
64
  }
66
65
  async loadCorePlugins() {
67
66
  const coreModules = await Promise.allSettled([
68
- import("./index-9tgyd3ep.js"),
67
+ import("./index-b1eq3qvs.js"),
69
68
  import("./index-rdm6e3rr.js"),
70
69
  import("./index-k9hb0b93.js"),
71
- import("./index-41m1exz7.js"),
70
+ import("./index-3rjnbp97.js"),
72
71
  import("./index-c7zy3n33.js"),
73
- import("./index-wdtxbebz.js"),
72
+ import("./index-fm6gqenc.js"),
74
73
  import("./index-npmvh1x9.js"),
75
- import("./index-q4ytrfx7.js"),
76
- import("./index-qthbtg9n.js"),
74
+ import("./index-6vry08rz.js"),
75
+ import("./index-wmvkjcjj.js"),
77
76
  import("./index-30p492yv.js"),
78
- import("./index-xn4tarcd.js"),
77
+ import("./index-t4qgjy5w.js"),
79
78
  import("./index-hefqxwht.js"),
80
79
  import("./index-a9g7hbj9.js")
81
80
  ]);
@@ -100,10 +99,14 @@ class PluginManager {
100
99
  async install(packageName) {
101
100
  logger.info("plugin-manager", `Installing ${packageName}...`);
102
101
  try {
103
- execSync(`npm install -g ${packageName}`, {
102
+ const result = Bun.spawnSync(["npm", "install", "-g", packageName], {
104
103
  timeout: 120000,
105
- stdio: "pipe"
104
+ stdout: "pipe",
105
+ stderr: "pipe"
106
106
  });
107
+ if (result.exitCode !== 0) {
108
+ throw new Error(result.stderr.toString().trim());
109
+ }
107
110
  } catch (err) {
108
111
  const message = err instanceof Error ? err.message : String(err);
109
112
  throw new Error(`Failed to install ${packageName}: ${message}`, {
@@ -151,9 +154,10 @@ class PluginManager {
151
154
  this.loaded.delete(packageName);
152
155
  }
153
156
  try {
154
- execSync(`npm uninstall -g ${packageName}`, {
157
+ Bun.spawnSync(["npm", "uninstall", "-g", packageName], {
155
158
  timeout: 60000,
156
- stdio: "pipe"
159
+ stdout: "pipe",
160
+ stderr: "pipe"
157
161
  });
158
162
  } catch {}
159
163
  this.registry = this.registry.filter((e) => e.packageName !== packageName);
@@ -471,5 +475,5 @@ class PluginManager {
471
475
 
472
476
  export { PluginManager };
473
477
 
474
- //# debugId=5AC5602856ACEA6F64756E2164756E21
475
- //# sourceMappingURL=plugin-system-v7a7xnhk.js.map
478
+ //# debugId=65B1E9D5172E7AEE64756E2164756E21
479
+ //# sourceMappingURL=plugin-system-7r9mb1tb.js.map