synsci 2.0.30 → 2.0.32-test.97.1

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 +18 -115
  2. package/package.json +2 -3
package/bin/synsci.mjs CHANGED
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // `npx synsci`: the OpenScience install wizard.
3
+ // `npx synsci`: the OpenScience installer and launcher.
4
4
  //
5
5
  // The npm package (and this bin) keep the historical `synsci` name so the
6
6
  // one-liner everyone knows keeps working; everything it installs is the
7
- // OpenScience CLI (`@synsci/openscience`, binary `openscience`), optionally with the
8
- // Atlas managed platform on top.
7
+ // OpenScience CLI (`@synsci/openscience`, binary `openscience`).
9
8
 
10
9
  // Hard guard against recursive invocation. If a check ever resolves to the
11
10
  // launcher itself, this prevents an infinite spawn chain that exhausts memory.
@@ -21,7 +20,6 @@ import { execFileSync, execSync, spawn } from "node:child_process"
21
20
  import { existsSync, readFileSync, realpathSync } from "node:fs"
22
21
  import { homedir } from "node:os"
23
22
  import { join, resolve } from "node:path"
24
- import { createInterface } from "node:readline"
25
23
  import { fileURLToPath } from "node:url"
26
24
  import { npmDistTag, opensciencePackageSpec } from "../lib/channel.mjs"
27
25
 
@@ -217,61 +215,11 @@ function isConnected() {
217
215
  if (!sessionPath) return false
218
216
  try {
219
217
  const data = JSON.parse(readFileSync(sessionPath, "utf-8"))
220
- if (!data.access_token || !data.expires_at) return false
221
- return new Date(data.expires_at) > new Date()
218
+ return typeof data.api_key === "string" && /^thk_[^.]+\.[A-Za-z0-9_-]+$/.test(data.api_key)
222
219
  } catch {
223
220
  return false
224
221
  }
225
222
  }
226
-
227
- function atlasVersion() {
228
- // `atlas` on PATH may be Ariga Atlas or the MongoDB Atlas CLI, whose
229
- // --version output also survives the digit filter. Only trust the command
230
- // when the global @synsci/atlas package is present to own it.
231
- const owned = runQuiet("npm ls -g @synsci/atlas --depth=0")
232
- if (!owned || !owned.includes("@synsci/atlas")) return null
233
- const raw = runQuiet("atlas --version")
234
- return raw ? raw.replace(/[^0-9.]/g, "") : null
235
- }
236
-
237
- // Install the Atlas CLI, or bring an existing install up to date. Returns
238
- // true when a working `atlas` binary is on PATH afterwards.
239
- async function installOrUpdateAtlas() {
240
- const current = atlasVersion()
241
- if (current) {
242
- const s = spinner("Checking Atlas CLI for updates...")
243
- const latest = runQuiet("npm view @synsci/atlas version")
244
- if (!latest || current === latest) {
245
- s.ok(`atlas ${current} ${DIM}(up to date)${RESET}`)
246
- return true
247
- }
248
- s.update(`Upgrading Atlas CLI ${current} → ${latest}...`)
249
- if (runQuiet("npm i -g @synsci/atlas@latest") !== null) {
250
- s.ok(`Upgraded Atlas CLI to ${latest}`)
251
- } else {
252
- s.warn(`Atlas CLI upgrade failed, continuing with ${current}`)
253
- }
254
- return true
255
- }
256
- const s = spinner("Installing Atlas CLI...")
257
- if (runQuiet("npm i -g @synsci/atlas@latest") !== null && atlasVersion()) {
258
- s.ok("Installed Atlas CLI")
259
- return true
260
- }
261
- s.warn(`Atlas CLI install failed, you can retry later: ${CYAN}npm i -g @synsci/atlas${RESET}`)
262
- return false
263
- }
264
-
265
- async function ask(question) {
266
- const rl = createInterface({ input: process.stdin, output: process.stdout })
267
- return new Promise((resolve) => {
268
- rl.question(question, (answer) => {
269
- rl.close()
270
- resolve(answer.trim())
271
- })
272
- })
273
- }
274
-
275
223
  async function main() {
276
224
  process.on("exit", () => process.stdout.write(SHOW_CURSOR))
277
225
  process.on("SIGINT", () => {
@@ -283,9 +231,7 @@ async function main() {
283
231
  console.log()
284
232
  for (const line of LOGO) console.log(` ${CYAN}${line}${RESET}`)
285
233
  console.log()
286
- console.log(
287
- ` ${BOLD}Synthetic Sciences${RESET} ${DIM}OpenScience, the open-source AI research workspace · Atlas, the research platform${RESET}`,
288
- )
234
+ console.log(` ${BOLD}Synthetic Sciences${RESET} ${DIM}OpenScience, the open-source AI research workspace${RESET}`)
289
235
  console.log()
290
236
 
291
237
  // --- Step 1: Install or upgrade the OpenScience CLI ---
@@ -366,66 +312,23 @@ async function main() {
366
312
  }
367
313
  }
368
314
 
369
- // --- Step 2: Choose a setup ---
370
- console.log()
371
- console.log(` ${BOLD}How do you want to run it?${RESET}`)
372
- console.log()
373
- console.log(
374
- ` ${BOLD}1${RESET} ${CYAN}OpenScience${RESET} ${DIM}free and open source, bring your own API keys, no account${RESET}`,
375
- )
376
- console.log(
377
- ` ${BOLD}2${RESET} ${CYAN}OpenScience + Atlas${RESET} ${DIM}managed models, wallet billing, research graph & compute${RESET}`,
378
- )
379
- console.log(
380
- ` ${BOLD}3${RESET} ${CYAN}Atlas CLI${RESET} ${DIM}just the Atlas research CLI — maps, runs, and compute from the terminal${RESET}`,
381
- )
382
- console.log()
383
-
384
- const setup = await ask(` ${DIM}❯${RESET} Choose [1/2/3]: `)
385
- console.log()
386
-
387
- if (setup === "3") {
388
- // Atlas-CLI-only path: install/upgrade, verify, hand off to `atlas`.
389
- // No workspace launch — this option exists for people who want the
390
- // research CLI on a box without opening the browser app.
391
- const installed = await installOrUpdateAtlas()
392
- if (!installed) process.exit(1)
393
- const s = spinner("Running atlas doctor...")
394
- if (runQuiet("atlas doctor") !== null) {
395
- s.ok("atlas doctor passed")
396
- } else {
397
- s.warn(`atlas doctor reported issues — run ${CYAN}atlas doctor${RESET} for details`)
398
- }
399
- if (isConnected()) {
400
- ok("Connected to Atlas")
401
- } else {
402
- console.log()
403
- console.log(
404
- ` ${DIM}Connect your Atlas account for managed credentials:${RESET} ${CYAN}openscience connect login${RESET}`,
405
- )
406
- }
407
- console.log()
408
- console.log(` ${BOLD}Next steps${RESET}`)
409
- console.log(` ${CYAN}atlas --help${RESET} ${DIM}see everything the CLI can do${RESET}`)
410
- console.log(` ${CYAN}atlas doctor${RESET} ${DIM}check credentials and environment${RESET}`)
315
+ // --- Step 2: Connect this device ---
316
+ if (isConnected()) {
317
+ ok("Connected to Synthetic Sciences")
318
+ } else {
411
319
  console.log()
412
- process.exit(0)
413
- }
414
-
415
- if (setup === "2") {
416
- await installOrUpdateAtlas()
417
- if (isConnected()) {
418
- ok("Connected to Atlas")
419
- } else {
420
- console.log()
421
- try {
422
- execCli(cliPath, ["connect", "login"], { stdio: "inherit" })
423
- } catch {}
320
+ try {
321
+ execCli(cliPath, ["login"], { stdio: "inherit" })
322
+ } catch {
323
+ warn("Synthetic Sciences sign-in did not finish")
324
+ process.exit(1)
424
325
  }
425
- } else {
426
- ok(`BYOK mode ${DIM}add provider keys inside the app (or via env vars like ANTHROPIC_API_KEY)${RESET}`)
326
+ if (!isConnected()) {
327
+ warn("A Synthetic Sciences account is required before the workspace can open")
328
+ process.exit(1)
329
+ }
330
+ ok("Connected to Synthetic Sciences")
427
331
  }
428
-
429
332
  console.log()
430
333
 
431
334
  // --- Step 3: Launch the workspace ---
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "synsci",
3
- "version": "2.0.30",
4
- "description": "Install wizard for OpenScience, the open-source AI research workspace (optionally with Atlas)",
3
+ "version": "2.0.32-test.97.1",
4
+ "description": "Launcher for OpenScience, the open-source AI research workspace",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "bin": {
@@ -15,7 +15,6 @@
15
15
  "openscience",
16
16
  "synsci",
17
17
  "synthetic-sciences",
18
- "atlas",
19
18
  "ai",
20
19
  "ml",
21
20
  "research",