offgrid-ai 0.3.6 → 0.3.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.mjs +49 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "offgrid-ai",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "Privacy-first CLI for running local LLMs — discover, configure, run, benchmark",
5
5
  "author": "Eeshan Srivastava (https://eeshans.com)",
6
6
  "type": "module",
package/src/cli.mjs CHANGED
@@ -789,6 +789,7 @@ async function uninstallCommand(argv) {
789
789
  // Non-interactive / forced: remove everything
790
790
  await removeDataDir();
791
791
  await removeSelf();
792
+ await removeShellPath();
792
793
  return;
793
794
  }
794
795
 
@@ -825,7 +826,8 @@ async function uninstallCommand(argv) {
825
826
  // Remove the npm package
826
827
  const confirmUninstall = await prompt.yesNo("Uninstall offgrid-ai npm package?", true);
827
828
  if (confirmUninstall) {
828
- removeSelf();
829
+ await removeSelf();
830
+ await removeShellPath();
829
831
  } else {
830
832
  console.log(pc.dim("Cancelled."));
831
833
  }
@@ -849,6 +851,51 @@ async function removeDataDir() {
849
851
  }
850
852
  }
851
853
 
854
+ async function removeShellPath() {
855
+ const { readFile, writeFile } = await import("node:fs/promises");
856
+ const { homedir } = await import("node:os");
857
+ const { promisify } = await import("node:util");
858
+ const { execFile } = await import("node:child_process");
859
+ let npmBin;
860
+ try {
861
+ const { stdout } = await promisify(execFile)("npm", ["bin", "-g"]);
862
+ npmBin = stdout.trim();
863
+ } catch { return; }
864
+ if (!npmBin) return;
865
+
866
+ const marker = "# Added by offgrid-ai installer";
867
+ const pathLine = `export PATH="${npmBin}:$PATH"`;
868
+ const rcFiles = [`${homedir()}/.zshrc`, `${homedir()}/.bashrc`, `${homedir()}/.bash_profile`];
869
+ let cleaned = false;
870
+
871
+ for (const rcFile of rcFiles) {
872
+ if (!existsSync(rcFile)) continue;
873
+ let content;
874
+ try { content = await readFile(rcFile, "utf8"); } catch { continue; }
875
+ if (!content.includes(npmBin) && !content.includes(marker)) continue;
876
+
877
+ const lines = content.split("\n");
878
+ const filtered = lines.filter((line, i) => {
879
+ // Remove the marker comment line
880
+ if (line.trim() === marker) return false;
881
+ // Remove the PATH export line added by the installer
882
+ if (line.trim() === pathLine) return false;
883
+ // Also remove a blank line that immediately precedes the marker (formatter)
884
+ if (i + 1 < lines.length && lines[i + 1].trim() === marker && line.trim() === "") return false;
885
+ return true;
886
+ });
887
+
888
+ if (filtered.length !== lines.length) {
889
+ await writeFile(rcFile, filtered.join("\n").replace(/\n{3,}/g, "\n\n") + "\n", "utf8");
890
+ console.log(pc.green(`✓ Cleaned PATH from ${rcFile}`));
891
+ cleaned = true;
892
+ }
893
+ }
894
+ if (!cleaned) {
895
+ console.log(pc.dim("No offgrid-ai PATH entries found in shell configs."));
896
+ }
897
+ }
898
+
852
899
  async function removeSelf() {
853
900
  console.log(pc.cyan("\nUninstalling offgrid-ai..."));
854
901
  const { spawn: spawnUninstall } = await import("node:child_process");
@@ -932,7 +979,7 @@ Usage:
932
979
  offgrid-ai Pick a model and run it
933
980
  offgrid-ai status Show running local models
934
981
  offgrid-ai stop Stop a running server (or: offgrid-ai stop <id>)
935
- offgrid-ai uninstall Remove offgrid-ai (optionally keep profiles)
982
+ offgrid-ai uninstall Remove offgrid-ai, clean up PATH, optionally keep profiles
936
983
  offgrid-ai help Show this help
937
984
  offgrid-ai version Show version
938
985