offgrid-ai 0.3.5 → 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.
- package/install.sh +53 -18
- package/package.json +1 -1
- package/src/cli.mjs +49 -2
package/install.sh
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
# 1. Checks for Node.js
|
|
12
12
|
# 2. If not found, installs it via nvm (no sudo needed)
|
|
13
13
|
# 3. Installs offgrid-ai globally via npm
|
|
14
|
-
# 4.
|
|
14
|
+
# 4. Adds npm global bin to PATH if needed
|
|
15
|
+
# 5. Runs offgrid-ai
|
|
15
16
|
#
|
|
16
17
|
# Flags:
|
|
17
18
|
# --dry-run Show what would happen without making changes
|
|
@@ -108,7 +109,7 @@ echo ""
|
|
|
108
109
|
printf "${BOLD}Installing offgrid-ai...${RESET}\n"
|
|
109
110
|
dry npm install -g offgrid-ai
|
|
110
111
|
|
|
111
|
-
# ──
|
|
112
|
+
# ── Dry-run early exit ──────────────────────────────────────────────────────
|
|
112
113
|
|
|
113
114
|
if $DRY_RUN; then
|
|
114
115
|
ok "offgrid-ai installed (dry-run)"
|
|
@@ -122,23 +123,52 @@ if $DRY_RUN; then
|
|
|
122
123
|
exit 0
|
|
123
124
|
fi
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
126
|
+
# ── Add npm global bin to PATH if needed ────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
NPM_BIN="$(npm bin -g 2>/dev/null)"
|
|
129
|
+
|
|
130
|
+
if ! command -v offgrid-ai &>/dev/null; then
|
|
131
|
+
if [[ -n "$NPM_BIN" && -x "$NPM_BIN/offgrid-ai" ]]; then
|
|
132
|
+
# Add to current session
|
|
133
|
+
export PATH="$NPM_BIN:$PATH"
|
|
134
|
+
ok "Added $NPM_BIN to PATH for this session"
|
|
135
|
+
|
|
136
|
+
# Add to shell config for future sessions (pick first existing or .zshrc)
|
|
137
|
+
ADDED_TO_RC=false
|
|
138
|
+
for RC_FILE in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile"; do
|
|
139
|
+
if [[ -f "$RC_FILE" || "$RC_FILE" == "$HOME/.zshrc" ]]; then
|
|
140
|
+
if ! grep -qF "$NPM_BIN" "$RC_FILE" 2>/dev/null; then
|
|
141
|
+
echo '' >> "$RC_FILE"
|
|
142
|
+
echo '# Added by offgrid-ai installer' >> "$RC_FILE"
|
|
143
|
+
echo "export PATH=\"$NPM_BIN:\$PATH\"" >> "$RC_FILE"
|
|
144
|
+
ok "Added $NPM_BIN to $RC_FILE"
|
|
145
|
+
ADDED_TO_RC=true
|
|
146
|
+
# Only add to one rc file to avoid duplicates
|
|
147
|
+
break
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
done
|
|
151
|
+
|
|
152
|
+
if ! $ADDED_TO_RC; then
|
|
153
|
+
warn "$NPM_BIN is already in a shell config file — restart your terminal to use offgrid-ai"
|
|
154
|
+
fi
|
|
155
|
+
else
|
|
156
|
+
echo ""
|
|
157
|
+
warn "offgrid-ai was installed but the binary wasn't found."
|
|
158
|
+
echo " Restart your terminal and run: offgrid-ai"
|
|
159
|
+
echo ""
|
|
160
|
+
printf "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}\n"
|
|
161
|
+
printf "${BOLD}${GREEN} offgrid-ai is ready!${RESET}\n"
|
|
162
|
+
printf "${BOLD}${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}\n"
|
|
163
|
+
echo ""
|
|
164
|
+
echo " Run: offgrid-ai"
|
|
165
|
+
echo ""
|
|
166
|
+
exit 0
|
|
167
|
+
fi
|
|
140
168
|
fi
|
|
141
169
|
|
|
170
|
+
ok "offgrid-ai installed at $(command -v offgrid-ai)"
|
|
171
|
+
|
|
142
172
|
# ── Done ─────────────────────────────────────────────────────────────────────
|
|
143
173
|
|
|
144
174
|
echo ""
|
|
@@ -149,7 +179,12 @@ echo ""
|
|
|
149
179
|
echo " First run will walk you through setting up everything you need"
|
|
150
180
|
echo " (llama-server, model backends, Pi)."
|
|
151
181
|
echo ""
|
|
152
|
-
|
|
182
|
+
if command -v offgrid-ai &>/dev/null; then
|
|
183
|
+
echo " Run: offgrid-ai"
|
|
184
|
+
else
|
|
185
|
+
echo " Run: source ~/.zshrc && offgrid-ai"
|
|
186
|
+
echo " (or open a new terminal)"
|
|
187
|
+
fi
|
|
153
188
|
echo ""
|
|
154
189
|
|
|
155
190
|
if [[ -t 0 ]] && ! $SKIP_RUN; then
|
package/package.json
CHANGED
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
|
|
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
|
|