offgrid-ai 0.8.1 → 0.8.3
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 +8 -6
- package/package.json +1 -1
- package/src/postinstall.mjs +66 -13
- package/src/updates.mjs +1 -4
package/install.sh
CHANGED
|
@@ -131,10 +131,10 @@ if command -v npm &>/dev/null; then
|
|
|
131
131
|
# Try the modern way first, then legacy
|
|
132
132
|
NPM_PREFIX="$(npm prefix -g 2>/dev/null || true)"
|
|
133
133
|
if [[ -n "$NPM_PREFIX" ]]; then
|
|
134
|
-
NPM_BIN="${NPM_PREFIX}/bin"
|
|
134
|
+
NPM_BIN="${NPM_PREFIX%/}/bin"
|
|
135
135
|
fi
|
|
136
136
|
# Validate: the binary should exist there
|
|
137
|
-
if [[ ! -
|
|
137
|
+
if [[ ! -x "$NPM_BIN/offgrid-ai" ]]; then
|
|
138
138
|
NPM_BIN=""
|
|
139
139
|
fi
|
|
140
140
|
fi
|
|
@@ -158,12 +158,14 @@ if [[ -n "$NPM_BIN" && -x "$NPM_BIN/offgrid-ai" ]]; then
|
|
|
158
158
|
|
|
159
159
|
# Add to shell config for future sessions (pick first existing or .zshrc)
|
|
160
160
|
ADDED_TO_RC=false
|
|
161
|
-
|
|
161
|
+
# Respect user's shell preference; default to .zshrc on macOS
|
|
162
|
+
[[ "$OSTYPE" == darwin* ]] && [[ -z "$DEFAULT_RC" ]] && DEFAULT_RC="$HOME/.zshrc"
|
|
163
|
+
RC_CANDIDATES=("${DEFAULT_RC:-}" "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.bash_profile")
|
|
164
|
+
for RC_FILE in "${RC_CANDIDATES[@]}"; do
|
|
165
|
+
[[ -z "$RC_FILE" ]] && continue
|
|
162
166
|
if [[ -f "$RC_FILE" || "$RC_FILE" == "$HOME/.zshrc" ]]; then
|
|
163
167
|
if ! grep -qF "$NPM_BIN" "$RC_FILE" 2>/dev/null; then
|
|
164
|
-
echo '' >> "$RC_FILE"
|
|
165
|
-
echo '# Added by offgrid-ai installer' >> "$RC_FILE"
|
|
166
|
-
echo "export PATH=\"$NPM_BIN:\$PATH\"" >> "$RC_FILE"
|
|
168
|
+
{ echo ''; echo '# Added by offgrid-ai installer'; echo "export PATH=\"$NPM_BIN:\$PATH\""; } >> "$RC_FILE"
|
|
167
169
|
ok "Added $NPM_BIN to $RC_FILE"
|
|
168
170
|
ADDED_TO_RC=true
|
|
169
171
|
# Only add to one rc file to avoid duplicates
|
package/package.json
CHANGED
package/src/postinstall.mjs
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { existsSync, readFileSync, appendFileSync } from "node:fs";
|
|
3
|
-
import {
|
|
3
|
+
import { mkdirSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
4
5
|
|
|
5
6
|
if (process.env.CI || process.env.OFFGRID_SKIP_POSTINSTALL) process.exit(0);
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
// npm v9+ sets npm_config_global="true" for global installs. Some contexts (Hermes,
|
|
9
|
+
// older npm, or wrapped installs) may not set it, so also check the prefix.
|
|
10
|
+
const isGlobalInstall = process.env.npm_config_global === "true" || isLikelyGlobalPrefix(process.env.npm_config_prefix, process.env.HOME);
|
|
11
|
+
if (!isGlobalInstall) process.exit(0);
|
|
7
12
|
|
|
8
13
|
const prefix = process.env.npm_config_prefix;
|
|
9
|
-
if (!prefix)
|
|
14
|
+
if (!prefix) {
|
|
15
|
+
console.log("offgrid-ai postinstall: npm global prefix not detected; skipping PATH update.");
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
10
18
|
|
|
11
19
|
if (isHermesPrefix(prefix, process.env.HOME)) {
|
|
12
20
|
console.log("offgrid-ai installed with a Hermes-managed npm prefix.");
|
|
@@ -19,35 +27,80 @@ const marker = "# Added by offgrid-ai installer";
|
|
|
19
27
|
const pathLine = `export PATH="${npmBin}:$PATH"`;
|
|
20
28
|
const currentPath = process.env.PATH ?? "";
|
|
21
29
|
|
|
22
|
-
if (currentPath.split(":").includes(npmBin))
|
|
30
|
+
if (currentPath.split(":").includes(npmBin)) {
|
|
31
|
+
console.log(`offgrid-ai is already on PATH (${npmBin})`);
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
23
34
|
|
|
24
35
|
const home = process.env.HOME;
|
|
25
|
-
if (!home)
|
|
36
|
+
if (!home) {
|
|
37
|
+
console.log("offgrid-ai postinstall: HOME not set; cannot update shell PATH.");
|
|
38
|
+
process.exit(0);
|
|
39
|
+
}
|
|
26
40
|
|
|
41
|
+
// Detect target shell config file. Prefer the file matching the user's shell.
|
|
27
42
|
const shell = process.env.SHELL ?? "";
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
const isZsh = /\bzsh$/u.test(shell);
|
|
44
|
+
const isBash = /\bbash$/u.test(shell);
|
|
45
|
+
|
|
46
|
+
let rcCandidates;
|
|
47
|
+
if (isZsh) {
|
|
48
|
+
rcCandidates = [".zshrc", ".zprofile", ".profile"];
|
|
49
|
+
} else if (isBash) {
|
|
50
|
+
rcCandidates = [".bashrc", ".bash_profile", ".profile"];
|
|
51
|
+
} else {
|
|
52
|
+
// Fallback: try common files, prefer existing ones
|
|
53
|
+
rcCandidates = [".bashrc", ".bash_profile", ".zshrc", ".zprofile", ".profile"];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const rcPaths = rcCandidates.map((name) => join(home, name));
|
|
57
|
+
let rcFile = rcPaths.find((file) => existsSync(file));
|
|
58
|
+
if (!rcFile) {
|
|
59
|
+
// No existing rc file: create the one matching the user's shell.
|
|
60
|
+
const defaultName = isZsh ? ".zshrc" : isBash ? ".bashrc" : ".bashrc";
|
|
61
|
+
rcFile = join(home, defaultName);
|
|
62
|
+
}
|
|
31
63
|
|
|
32
|
-
const rcFile = rcCandidates.find((file) => existsSync(file)) ?? rcCandidates[0];
|
|
33
64
|
let content = "";
|
|
34
65
|
try {
|
|
35
66
|
content = existsSync(rcFile) ? readFileSync(rcFile, "utf8") : "";
|
|
36
|
-
} catch {
|
|
67
|
+
} catch (err) {
|
|
68
|
+
console.log(`offgrid-ai postinstall: could not read ${rcFile}: ${err.message}`);
|
|
37
69
|
process.exit(0);
|
|
38
70
|
}
|
|
39
71
|
|
|
40
72
|
if (!content.includes(npmBin)) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
73
|
+
try {
|
|
74
|
+
mkdirSync(dirname(rcFile), { recursive: true });
|
|
75
|
+
appendFileSync(rcFile, `${content.endsWith("\n") || content.length === 0 ? "" : "\n"}\n${marker}\n${pathLine}\n`, "utf8");
|
|
76
|
+
console.log(`offgrid-ai added ${npmBin} to ${rcFile}`);
|
|
77
|
+
console.log(`Open a new terminal, or run: source ${rcFile}`);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.log(`offgrid-ai postinstall: could not write to ${rcFile}: ${err.message}`);
|
|
80
|
+
}
|
|
44
81
|
} else {
|
|
45
82
|
console.log(`offgrid-ai is installed in ${npmBin}`);
|
|
46
83
|
console.log(`Open a new terminal if the command is not found yet.`);
|
|
47
84
|
}
|
|
48
85
|
|
|
86
|
+
if (process.getuid?.() === 0) {
|
|
87
|
+
console.log("Warning: offgrid-ai was installed as root. PATH was added to root's shell config, not the regular user's.");
|
|
88
|
+
console.log("If you installed with sudo, run the installer as your normal user instead, or manually add the line above to your user's shell config.");
|
|
89
|
+
}
|
|
90
|
+
|
|
49
91
|
function isHermesPrefix(prefix, home) {
|
|
50
92
|
const normalized = prefix.replace(/\\/gu, "/");
|
|
51
93
|
if (normalized.includes("/.hermes/")) return true;
|
|
52
94
|
return Boolean(home && normalized === `${home.replace(/\\/gu, "/")}/.hermes/node`);
|
|
53
95
|
}
|
|
96
|
+
|
|
97
|
+
function isLikelyGlobalPrefix(prefix, home) {
|
|
98
|
+
if (!prefix || !home) return false;
|
|
99
|
+
const normalized = prefix.replace(/\\/gu, "/");
|
|
100
|
+
const homeNormalized = home.replace(/\\/gu, "/");
|
|
101
|
+
// Common global prefixes: /usr/local, /opt/homebrew, nvm paths, ~/.npm-global, ~/.local
|
|
102
|
+
return normalized.startsWith("/usr/") ||
|
|
103
|
+
normalized.startsWith("/opt/") ||
|
|
104
|
+
normalized.startsWith(homeNormalized) ||
|
|
105
|
+
/\/versions\/node\/v?\d/u.test(normalized);
|
|
106
|
+
}
|
package/src/updates.mjs
CHANGED
|
@@ -20,10 +20,7 @@ export async function checkForUpdate({ now = Date.now(), fetchImpl = globalThis.
|
|
|
20
20
|
if (cached.currentVersion === currentVersion) {
|
|
21
21
|
return updateResult(currentVersion, cached.latestVersion);
|
|
22
22
|
}
|
|
23
|
-
// Cache is from a different version —
|
|
24
|
-
if (cached.latestVersion && !isNewerVersion(cached.latestVersion, currentVersion)) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
23
|
+
// Cache is from a different installed version — invalidate and refetch
|
|
27
24
|
}
|
|
28
25
|
|
|
29
26
|
try {
|