synsci 1.1.122 → 1.1.124
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/bin/synsci.mjs +65 -10
- package/package.json +2 -2
package/bin/synsci.mjs
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
// Hard guard against recursive invocation. The launcher binary and the real
|
|
4
|
+
// @synsci/cli binary share the name `synsci`; if a check ever resolves to
|
|
5
|
+
// the launcher itself, this prevents an infinite spawn chain that exhausts
|
|
6
|
+
// memory.
|
|
7
|
+
if (process.env.__SYNSCI_LAUNCHER_PID) {
|
|
8
|
+
process.stderr.write(
|
|
9
|
+
`synsci: launcher invoked recursively (parent pid ${process.env.__SYNSCI_LAUNCHER_PID}). Exiting.\n`,
|
|
10
|
+
)
|
|
11
|
+
process.exit(2)
|
|
12
|
+
}
|
|
13
|
+
process.env.__SYNSCI_LAUNCHER_PID = String(process.pid)
|
|
14
|
+
|
|
15
|
+
import { execFileSync, execSync, spawn } from "node:child_process"
|
|
16
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs"
|
|
5
17
|
import { homedir } from "node:os"
|
|
6
18
|
import { join } from "node:path"
|
|
7
19
|
import { createInterface } from "node:readline"
|
|
20
|
+
import { fileURLToPath } from "node:url"
|
|
21
|
+
|
|
22
|
+
const SELF_PATH = (() => {
|
|
23
|
+
try { return realpathSync(fileURLToPath(import.meta.url)) } catch { return "" }
|
|
24
|
+
})()
|
|
8
25
|
|
|
9
26
|
const BOLD = "\x1b[1m"
|
|
10
27
|
const DIM = "\x1b[2m"
|
|
@@ -49,7 +66,42 @@ function runQuiet(cmd) {
|
|
|
49
66
|
catch { return null }
|
|
50
67
|
}
|
|
51
68
|
|
|
52
|
-
function
|
|
69
|
+
function runFileQuiet(file, args = []) {
|
|
70
|
+
try { return execFileSync(file, args, { encoding: "utf-8", stdio: "pipe" }).trim() }
|
|
71
|
+
catch { return null }
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isLauncherPath(p) {
|
|
75
|
+
try {
|
|
76
|
+
const real = realpathSync(p)
|
|
77
|
+
if (SELF_PATH && real === SELF_PATH) return true
|
|
78
|
+
if (real.includes("/_npx/")) return true
|
|
79
|
+
return false
|
|
80
|
+
} catch { return false }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Returns the absolute path to the real @synsci/cli binary, never the launcher
|
|
84
|
+
// itself. Walks past PATH entries pointing at this script or any npx shim.
|
|
85
|
+
function resolveCli() {
|
|
86
|
+
// 1. Global npm prefix (where `npm i -g @synsci/cli` puts it)
|
|
87
|
+
const prefix = runQuiet("npm prefix -g")
|
|
88
|
+
if (prefix) {
|
|
89
|
+
const cand = join(prefix, "bin", "synsci")
|
|
90
|
+
if (existsSync(cand) && !isLauncherPath(cand)) return cand
|
|
91
|
+
}
|
|
92
|
+
// 2. ~/.synsc/bin/synsci (used by @synsci/cli postinstall on some setups)
|
|
93
|
+
const synscBin = join(homedir(), ".synsc", "bin", "synsci")
|
|
94
|
+
if (existsSync(synscBin) && !isLauncherPath(synscBin)) return synscBin
|
|
95
|
+
// 3. Walk every PATH entry, return first that is NOT a launcher
|
|
96
|
+
for (const dir of (process.env.PATH || "").split(":")) {
|
|
97
|
+
if (!dir) continue
|
|
98
|
+
const cand = join(dir, "synsci")
|
|
99
|
+
if (existsSync(cand) && !isLauncherPath(cand)) return cand
|
|
100
|
+
}
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function isInstalled() { return resolveCli() !== null }
|
|
53
105
|
|
|
54
106
|
function isConnected() {
|
|
55
107
|
const xdgData = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share")
|
|
@@ -81,8 +133,9 @@ async function main() {
|
|
|
81
133
|
console.log()
|
|
82
134
|
|
|
83
135
|
// --- Step 1: Install or upgrade ---
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
let cliPath = resolveCli()
|
|
137
|
+
if (cliPath) {
|
|
138
|
+
const raw = runFileQuiet(cliPath, ["--version"]) || "unknown"
|
|
86
139
|
const isDev = raw === "local" || raw.includes("-")
|
|
87
140
|
if (isDev) {
|
|
88
141
|
ok(`synsci ${DIM}(dev build)${RESET}`)
|
|
@@ -95,7 +148,7 @@ async function main() {
|
|
|
95
148
|
} else {
|
|
96
149
|
s.update(`Upgrading ${current} \u2192 ${latest}...`)
|
|
97
150
|
try {
|
|
98
|
-
|
|
151
|
+
execFileSync(cliPath, ["upgrade"], { stdio: "pipe" })
|
|
99
152
|
s.ok(`Upgraded to ${latest}`)
|
|
100
153
|
} catch {
|
|
101
154
|
s.warn(`Upgrade failed, continuing with ${current}`)
|
|
@@ -106,9 +159,11 @@ async function main() {
|
|
|
106
159
|
const s = spinner("Installing synsci...")
|
|
107
160
|
try {
|
|
108
161
|
execSync("npm i -g @synsci/cli@latest", { stdio: "pipe" })
|
|
162
|
+
cliPath = resolveCli()
|
|
163
|
+
if (!cliPath) throw new Error("real CLI not on PATH after install")
|
|
109
164
|
s.ok("Installed synsci")
|
|
110
|
-
} catch {
|
|
111
|
-
s.fail(
|
|
165
|
+
} catch (e) {
|
|
166
|
+
s.fail(`Install failed${e && e.message ? ": " + e.message : ""}`)
|
|
112
167
|
console.log(`\n Try manually: ${CYAN}npm i -g @synsci/cli${RESET}\n`)
|
|
113
168
|
process.exit(1)
|
|
114
169
|
}
|
|
@@ -120,7 +175,7 @@ async function main() {
|
|
|
120
175
|
} else {
|
|
121
176
|
console.log()
|
|
122
177
|
try {
|
|
123
|
-
|
|
178
|
+
execFileSync(cliPath, ["connect", "login"], { stdio: "inherit" })
|
|
124
179
|
} catch {}
|
|
125
180
|
}
|
|
126
181
|
|
|
@@ -137,7 +192,7 @@ async function main() {
|
|
|
137
192
|
console.log()
|
|
138
193
|
|
|
139
194
|
const cmd = choice === "2" ? ["web"] : []
|
|
140
|
-
const child = spawn(
|
|
195
|
+
const child = spawn(cliPath, cmd, { stdio: "inherit" })
|
|
141
196
|
child.on("close", (code) => process.exit(code ?? 0))
|
|
142
197
|
}
|
|
143
198
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synsci",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.124",
|
|
4
4
|
"description": "One command to install, connect, and launch Synthetic Sciences CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/
|
|
23
|
+
"url": "git+https://github.com/synthetic-sciences/synsci-cli.git"
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://syntheticsciences.ai"
|
|
26
26
|
}
|