synsci 1.2.2 → 1.2.4

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/bin/synsci.mjs +53 -6
  2. package/package.json +2 -2
package/bin/synsci.mjs CHANGED
@@ -115,6 +115,19 @@ function resolveCli() {
115
115
  return null
116
116
  }
117
117
 
118
+ // The deprecated `@synsci/cli` package links the same `openscience` bin. npm
119
+ // refuses to overwrite a bin file owned by another package (EEXIST), so a
120
+ // stale global install dead-ends the upgrade — and its old binary shadows the
121
+ // real one on PATH. `npm ls` exits nonzero when the package is absent but
122
+ // still prints JSON, so read stdout either way.
123
+ function hasDeprecatedCli() {
124
+ let out = ""
125
+ try { out = execSync("npm ls -g @synsci/cli --depth=0 --json", { encoding: "utf-8", stdio: "pipe" }) }
126
+ catch (e) { out = e && typeof e.stdout === "string" ? e.stdout : "" }
127
+ try { return Boolean(JSON.parse(out).dependencies["@synsci/cli"]) }
128
+ catch { return false }
129
+ }
130
+
118
131
  function isConnected() {
119
132
  const xdgData = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share")
120
133
  const sessionPath = join(xdgData, "openscience", "openscience-session.json")
@@ -149,6 +162,15 @@ async function main() {
149
162
  console.log()
150
163
 
151
164
  // --- Step 1: Install or upgrade the OpenScience CLI ---
165
+ if (hasDeprecatedCli()) {
166
+ const s = spinner("Removing the deprecated @synsci/cli so it can't shadow the openscience command...")
167
+ if (runQuiet("npm rm -g @synsci/cli") !== null) {
168
+ s.ok("Removed the deprecated @synsci/cli")
169
+ } else {
170
+ s.warn(`Couldn't remove the deprecated @synsci/cli — if install fails, run: ${CYAN}npm rm -g @synsci/cli${RESET}`)
171
+ }
172
+ }
173
+
152
174
  let cliPath = resolveCli()
153
175
  if (cliPath) {
154
176
  const raw = runFileQuiet(cliPath, ["--version"]) || "unknown"
@@ -174,14 +196,39 @@ async function main() {
174
196
  } else {
175
197
  const s = spinner("Installing OpenScience...")
176
198
  try {
177
- execSync("npm i -g @synsci/openscience@latest", { stdio: "pipe" })
199
+ try {
200
+ execSync("npm i -g @synsci/openscience@latest", { stdio: "pipe" })
201
+ } catch (e) {
202
+ // npm refuses to overwrite a bin file owned by another package
203
+ // (EEXIST). If the conflict is the deprecated @synsci/cli, remove it
204
+ // and retry once before falling back to the standalone installer.
205
+ const stderr = e && e.stderr ? String(e.stderr) : ""
206
+ const conflict = stderr.includes("EEXIST") && (stderr.includes("@synsci/cli") || hasDeprecatedCli())
207
+ if (!conflict) throw e
208
+ s.update("Removing the deprecated @synsci/cli so it can't shadow the openscience command...")
209
+ runQuiet("npm rm -g @synsci/cli")
210
+ s.update("Retrying the OpenScience install...")
211
+ execSync("npm i -g @synsci/openscience@latest", { stdio: "pipe" })
212
+ }
178
213
  cliPath = resolveCli()
179
214
  if (!cliPath) throw new Error("openscience not on PATH after install")
180
215
  s.ok("Installed OpenScience")
181
- } catch (e) {
182
- s.fail(`Install failed${e && e.message ? ": " + e.message : ""}`)
183
- console.log(`\n Try manually: ${CYAN}npm i -g @synsci/openscience${RESET}\n`)
184
- process.exit(1)
216
+ } catch {
217
+ // Global npm installs commonly fail on permissions. Fall back to the
218
+ // standalone installer, which lands in ~/.openscience/bin without sudo
219
+ // (resolveCli already checks that location).
220
+ s.update("npm -g failed, trying the standalone installer...")
221
+ try {
222
+ execSync("curl -fsSL https://openscience.sh/install | bash", { stdio: "pipe" })
223
+ cliPath = resolveCli()
224
+ if (!cliPath) throw new Error("openscience not found after install")
225
+ s.ok("Installed OpenScience")
226
+ } catch (e2) {
227
+ s.fail(`Install failed${e2 && e2.message ? ": " + e2.message : ""}`)
228
+ console.log(`\n Try manually: ${CYAN}npm i -g @synsci/openscience${RESET}`)
229
+ console.log(` or: ${CYAN}curl -fsSL https://openscience.sh/install | bash${RESET}\n`)
230
+ process.exit(1)
231
+ }
185
232
  }
186
233
  }
187
234
 
@@ -226,7 +273,7 @@ async function main() {
226
273
  console.log(` ${DIM}Opening the workspace in your browser…${RESET}`)
227
274
  console.log()
228
275
 
229
- const child = spawn(cliPath, ["web"], { stdio: "inherit" })
276
+ const child = spawn(cliPath, ["web", ...process.argv.slice(2)], { stdio: "inherit" })
230
277
  child.on("close", (code) => process.exit(code ?? 0))
231
278
  }
232
279
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synsci",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Install wizard for OpenScience, the open-source AI research workspace (optionally with Atlas)",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/synthetic-sciences/OpenScience.git"
25
+ "url": "git+https://github.com/synthetic-sciences/openscience.git"
26
26
  },
27
27
  "homepage": "https://syntheticsciences.ai"
28
28
  }