@plumpslabs/fennec-cli 1.13.6 → 1.13.7

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/index.js CHANGED
@@ -2091,7 +2091,7 @@ function hexColor(color) {
2091
2091
  }
2092
2092
  var fennecOrange2 = hexColor("#FF6432");
2093
2093
  var fennecGold = hexColor("#FFB347");
2094
- var VERSION = "1.13.6";
2094
+ var VERSION = "1.13.7";
2095
2095
  var cachedBanner = null;
2096
2096
  var cachedCompact = null;
2097
2097
  function generateBanner() {
@@ -2242,13 +2242,14 @@ var COMMANDS = {
2242
2242
  kill: {
2243
2243
  name: "kill",
2244
2244
  usage: "kill <pid|name|all>",
2245
- summary: "Kill a process by PID, name, or kill all user processes",
2246
- description: "Permanently removes a tracked app (unlike `stop`, which keeps it). Prompts before killing.",
2245
+ summary: "Kill a Fennec-tracked process (by PID, tracked name, or all tracked)",
2246
+ description: "Permanently removes a tracked app (unlike `stop`, which keeps it). By NAME it only matches Fennec-tracked apps \u2014 use an explicit PID to kill a system process. Prompts before killing.",
2247
2247
  options: [
2248
2248
  ["--signal <sig>", "Signal to send (default: SIGTERM). e.g. SIGKILL, SIGINT"],
2249
- ["--all, -a", "Kill all user processes (asks for confirmation)"]
2249
+ ["--all, -a", "Kill ALL tracked apps (asks for confirmation)"],
2250
+ ["-y, --yes", "Skip the confirmation prompt"]
2250
2251
  ],
2251
- examples: ["kill web", "kill 12345 --signal SIGKILL", "kill all"]
2252
+ examples: ["kill web", "kill 12345 --signal SIGKILL", "kill all -y"]
2252
2253
  },
2253
2254
  supervisor: {
2254
2255
  name: "supervisor",
@@ -4248,28 +4249,9 @@ async function killCommand(args2) {
4248
4249
  targetPid = trackedMatch.pid;
4249
4250
  displayName = `${trackedMatch.name} (PID ${targetPid})`;
4250
4251
  } else {
4251
- const currentPid = process.pid;
4252
- let matches = getSystemProcesses({ name: rawTarget, userOnly: true, sortBy: "cpu" });
4253
- matches = matches.filter((m) => m.pid !== currentPid);
4254
- if (matches.length === 0) {
4255
- console.error(renderError("Process not found", `No running process matching "${rawTarget}"`));
4256
- process.exit(1);
4257
- }
4258
- if (matches.length > 1) {
4259
- console.error(`
4260
- ${pc8.bold(`Multiple processes match "${rawTarget}":`)}`);
4261
- const selected = await selectPrompt("Select which to kill:", matches.map((p, i) => ({ value: String(i), label: `${p.name} (PID ${p.pid})`, description: `${p.command.slice(0, 80)} \u2014 CPU: ${p.cpuPercent}% MEM: ${p.memPercent}%` })));
4262
- if (selected === null) {
4263
- console.error(` ${pc8.dim("Cancelled")}`);
4264
- return;
4265
- }
4266
- const idx = parseInt(selected, 10);
4267
- targetPid = matches[idx].pid;
4268
- displayName = `${matches[idx].name} (PID ${targetPid})`;
4269
- } else {
4270
- targetPid = matches[0].pid;
4271
- displayName = `${matches[0].name} (PID ${targetPid})`;
4272
- }
4252
+ console.error(renderError("Not tracked", `No tracked process named "${rawTarget}".
4253
+ Use ${pc8.cyan(`fennec kill <pid>`)} to kill a system process by its PID.`));
4254
+ process.exit(1);
4273
4255
  }
4274
4256
  }
4275
4257
  const confirmed = force || await confirmPrompt(`Kill ${pc8.bold(displayName)} with ${pc8.yellow(signal)}?`, false);
@@ -4623,35 +4605,27 @@ import { mkdirSync as mkdirSync6 } from "fs";
4623
4605
  import { resolve as resolve6 } from "path";
4624
4606
  import { homedir as homedir4 } from "os";
4625
4607
  async function restartCommand(args2) {
4626
- const name = args2[0];
4627
- if (!name) {
4628
- console.error(renderError("Missing process name/pid", "Usage: fennec restart <name|pid>"));
4608
+ const raw = args2[0];
4609
+ if (!raw) {
4610
+ console.error(renderError("Missing process name/pid", "Usage: fennec restart <name|pid> [-y]"));
4629
4611
  process.exit(1);
4630
4612
  }
4631
4613
  const tracked = readTracked();
4632
- let trackedEntry = tracked.find((t) => t.name === name);
4633
- let targetPid;
4634
- if (trackedEntry) {
4635
- targetPid = trackedEntry.pid;
4636
- } else {
4637
- const pid = parseInt(name, 10);
4638
- if (!isNaN(pid) && String(pid) === name) {
4639
- targetPid = pid;
4640
- } else {
4641
- const processes = getSystemProcesses({ name, userOnly: true, limit: 1 });
4642
- if (processes.length === 0) {
4643
- console.error(renderError("Process not found", `No process matching "${name}"`));
4644
- process.exit(1);
4645
- }
4646
- targetPid = processes[0].pid;
4647
- }
4614
+ const pidNum = parseInt(raw, 10);
4615
+ const trackedEntry = tracked.find((t) => t.name === raw) ?? (!isNaN(pidNum) && String(pidNum) === raw ? tracked.find((t) => t.pid === pidNum) : void 0);
4616
+ if (!trackedEntry) {
4617
+ console.error(renderError("Not tracked", `No tracked process named or with PID "${raw}".
4618
+ fennec restart only re-spawns Fennec-tracked apps (from their saved config).`));
4619
+ process.exit(1);
4648
4620
  }
4649
- const confirmed = await confirmPrompt(`Restart ${pc11.bold(`${name} (PID ${targetPid})`)}?`, false);
4621
+ const targetPid = trackedEntry.pid;
4622
+ const force = args2.includes("-y") || args2.includes("--yes");
4623
+ const confirmed = force || await confirmPrompt(`Restart ${pc11.bold(`${trackedEntry.name} (PID ${targetPid})`)}?`, false);
4650
4624
  if (!confirmed) {
4651
4625
  console.error(` ${pc11.dim("Cancelled")}`);
4652
4626
  return;
4653
4627
  }
4654
- const spinner = createSpinner(`Stopping PID ${targetPid}...`);
4628
+ const spinner = createSpinner(`Stopping ${trackedEntry.name} (PID ${targetPid})...`);
4655
4629
  const killed = killProcess(targetPid, "SIGTERM");
4656
4630
  if (!killed) {
4657
4631
  spinner.fail(`Failed to stop PID ${targetPid}`);
@@ -4663,35 +4637,31 @@ async function restartCommand(args2) {
4663
4637
  killProcess(targetPid, "SIGKILL");
4664
4638
  await new Promise((r) => setTimeout(r, 500));
4665
4639
  }
4666
- spinner.succeed(`${name} stopped`);
4667
- if (trackedEntry) {
4668
- const respawnSpinner = createSpinner(`Re-spawning ${trackedEntry.name}...`);
4669
- try {
4670
- const cmdParts = resolveArgs(trackedEntry);
4671
- const logDir = resolve6(homedir4(), ".fennec", "logs");
4672
- mkdirSync6(logDir, { recursive: true });
4673
- const logFilePath = resolve6(logDir, `${trackedEntry.name}.log`);
4674
- const child = spawnDaemon({ cmdParts, name: trackedEntry.name, cwd: trackedEntry.cwd, logFilePath, env: buildSpawnEnv(trackedEntry.env), logMode: trackedEntry.logMode });
4675
- removeTrackedByPid(targetPid);
4676
- addTracked({
4677
- name: trackedEntry.name,
4678
- pid: child.pid ?? 0,
4679
- command: trackedEntry.command,
4680
- args: cmdParts,
4681
- port: trackedEntry.port,
4682
- cwd: trackedEntry.cwd,
4683
- env: trackedEntry.env,
4684
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
4685
- autoRestart: trackedEntry.autoRestart,
4686
- logMode: trackedEntry.logMode
4687
- });
4688
- respawnSpinner.succeed(`${trackedEntry.name} restarted (PID: ${child.pid})`);
4689
- } catch (error) {
4690
- respawnSpinner.fail(`Failed to re-spawn ${trackedEntry.name}: ${String(error)}`);
4691
- console.error(` ${pc11.dim("Config preserved. Re-run manually:")} ${renderCommand(trackedEntry.command)}`);
4692
- }
4693
- } else {
4694
- console.error(` ${pc11.dim("No tracked config found. Re-run manually:")} ${renderCommand(name)}`);
4640
+ spinner.succeed(`${trackedEntry.name} stopped`);
4641
+ const respawnSpinner = createSpinner(`Re-spawning ${trackedEntry.name}...`);
4642
+ try {
4643
+ const cmdParts = resolveArgs(trackedEntry);
4644
+ const logDir = resolve6(homedir4(), ".fennec", "logs");
4645
+ mkdirSync6(logDir, { recursive: true });
4646
+ const logFilePath = resolve6(logDir, `${trackedEntry.name}.log`);
4647
+ const child = spawnDaemon({ cmdParts, name: trackedEntry.name, cwd: trackedEntry.cwd, logFilePath, env: buildSpawnEnv(trackedEntry.env), logMode: trackedEntry.logMode });
4648
+ removeTrackedByPid(targetPid);
4649
+ addTracked({
4650
+ name: trackedEntry.name,
4651
+ pid: child.pid ?? 0,
4652
+ command: trackedEntry.command,
4653
+ args: cmdParts,
4654
+ port: trackedEntry.port,
4655
+ cwd: trackedEntry.cwd,
4656
+ env: trackedEntry.env,
4657
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
4658
+ autoRestart: trackedEntry.autoRestart,
4659
+ logMode: trackedEntry.logMode
4660
+ });
4661
+ respawnSpinner.succeed(`${trackedEntry.name} restarted (PID: ${child.pid})`);
4662
+ } catch (error) {
4663
+ respawnSpinner.fail(`Failed to re-spawn ${trackedEntry.name}: ${String(error)}`);
4664
+ console.error(` ${pc11.dim("Config preserved. Re-run manually:")} ${renderCommand(trackedEntry.command)}`);
4695
4665
  }
4696
4666
  }
4697
4667