@genspark/cli 1.0.20 → 1.0.21

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.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Lazy download + integrity-verified caching of the native gsk-mesh binary.
3
+ *
4
+ * Cache layout under ~/.genspark-tool-cli/bin/ :
5
+ * gsk-mesh[.exe] the native binary
6
+ * .gsk-mesh-version the version string the binary was installed at
7
+ * .gsk-mesh-sha256 the expected sha256 for that binary
8
+ *
9
+ * Security note (per-run integrity check — gen-spark#32059): a cached binary
10
+ * is exec'd directly on every `gsk mesh ...`, so a local process that can write
11
+ * to bin/ could otherwise plant code that runs as the user. On every cache hit
12
+ * we re-hash the file and compare:
13
+ * - if it's still at PINNED_VERSION, the expected sha is CHECKSUMS[target],
14
+ * which is compiled into the published @genspark/cli (tamper-resistant);
15
+ * - otherwise (upgraded past the pin via `gsk mesh upgrade`), we compare
16
+ * against the .gsk-mesh-sha256 stamp.
17
+ * A mismatch re-downloads the pinned version rather than exec'ing a binary we
18
+ * can't vouch for.
19
+ */
20
+ /** True if a gsk-mesh binary is already cached for the current target. */
21
+ export declare function isMeshInstalled(): boolean;
22
+ /** The version string the cached binary was installed at, or null. */
23
+ export declare function getInstalledMeshVersion(): string | null;
24
+ /**
25
+ * Ensure the native gsk-mesh binary is present, current, and intact.
26
+ * Returns the absolute path to the verified binary.
27
+ */
28
+ export declare function ensureMeshBinary(): Promise<string>;
29
+ /**
30
+ * Download a specific version+target from `url`, verify its sha256, install it
31
+ * atomically, and update the version/sha stamps. Shared by first-run
32
+ * (`ensureMeshBinary`) and `gsk mesh upgrade` (which passes a newer version).
33
+ */
34
+ export declare function downloadAndInstall(url: string, expectedSha: string, version: string, target: string): Promise<void>;
35
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/mesh/download.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA8BH,0EAA0E;AAC1E,wBAAgB,eAAe,IAAI,OAAO,CAMzC;AAED,sEAAsE;AACtE,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AA8BD;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CA0CxD;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Lazy download + integrity-verified caching of the native gsk-mesh binary.
3
+ *
4
+ * Cache layout under ~/.genspark-tool-cli/bin/ :
5
+ * gsk-mesh[.exe] the native binary
6
+ * .gsk-mesh-version the version string the binary was installed at
7
+ * .gsk-mesh-sha256 the expected sha256 for that binary
8
+ *
9
+ * Security note (per-run integrity check — gen-spark#32059): a cached binary
10
+ * is exec'd directly on every `gsk mesh ...`, so a local process that can write
11
+ * to bin/ could otherwise plant code that runs as the user. On every cache hit
12
+ * we re-hash the file and compare:
13
+ * - if it's still at PINNED_VERSION, the expected sha is CHECKSUMS[target],
14
+ * which is compiled into the published @genspark/cli (tamper-resistant);
15
+ * - otherwise (upgraded past the pin via `gsk mesh upgrade`), we compare
16
+ * against the .gsk-mesh-sha256 stamp.
17
+ * A mismatch re-downloads the pinned version rather than exec'ing a binary we
18
+ * can't vouch for.
19
+ */
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import * as os from 'os';
23
+ import * as crypto from 'crypto';
24
+ import * as https from 'https';
25
+ import { spawn } from 'child_process';
26
+ import { PINNED_VERSION, CHECKSUMS, cdnUrl, binExt, currentTarget, } from './manifest.js';
27
+ import { info, debug } from '../logger.js';
28
+ const BIN_DIR = path.join(os.homedir(), '.genspark-tool-cli', 'bin');
29
+ // Monotonic counter so concurrent downloadAndInstall calls within one process
30
+ // never share a temp path (pid alone isn't enough — same-pid concurrency).
31
+ let _tmpCounter = 0;
32
+ function binPath(target) {
33
+ return path.join(BIN_DIR, `gsk-mesh${binExt(target)}`);
34
+ }
35
+ const VERSION_STAMP = path.join(BIN_DIR, '.gsk-mesh-version');
36
+ const SHA_STAMP = path.join(BIN_DIR, '.gsk-mesh-sha256');
37
+ /** True if a gsk-mesh binary is already cached for the current target. */
38
+ export function isMeshInstalled() {
39
+ try {
40
+ return fs.existsSync(binPath(currentTarget()));
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ /** The version string the cached binary was installed at, or null. */
47
+ export function getInstalledMeshVersion() {
48
+ return readStamp(VERSION_STAMP);
49
+ }
50
+ /** sha256 of a file as lowercase hex, or null if it can't be read. */
51
+ function fileSha256(file) {
52
+ try {
53
+ const buf = fs.readFileSync(file);
54
+ return crypto.createHash('sha256').update(buf).digest('hex');
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ function readStamp(file) {
61
+ try {
62
+ return fs.readFileSync(file, 'utf-8').trim();
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ /**
69
+ * The expected sha256 for the currently-cached binary:
70
+ * - at PINNED_VERSION → the compiled-in CHECKSUMS value (tamper-resistant);
71
+ * - otherwise → the on-disk .gsk-mesh-sha256 stamp.
72
+ */
73
+ function expectedShaForCached(target, installedVersion) {
74
+ if (installedVersion === PINNED_VERSION)
75
+ return CHECKSUMS[target];
76
+ return readStamp(SHA_STAMP);
77
+ }
78
+ /**
79
+ * Ensure the native gsk-mesh binary is present, current, and intact.
80
+ * Returns the absolute path to the verified binary.
81
+ */
82
+ export async function ensureMeshBinary() {
83
+ const target = currentTarget();
84
+ const expectedPinned = CHECKSUMS[target];
85
+ const localPath = binPath(target);
86
+ if (fs.existsSync(localPath)) {
87
+ const installedVersion = readStamp(VERSION_STAMP);
88
+ if (installedVersion === PINNED_VERSION) {
89
+ // Same version we ship as the floor: verify integrity every run.
90
+ const expected = expectedShaForCached(target, installedVersion);
91
+ const actual = fileSha256(localPath);
92
+ if (expected && actual === expected) {
93
+ debug(`gsk-mesh cached + verified at ${localPath} (v${installedVersion})`);
94
+ return localPath;
95
+ }
96
+ info(`gsk-mesh: cached binary failed integrity check (expected ${expected ?? '?'}, ` +
97
+ `got ${actual ?? '?'}) — re-downloading v${PINNED_VERSION}`);
98
+ }
99
+ else if (installedVersion) {
100
+ // Upgraded past the pin via `gsk mesh upgrade`. Verify against the stamp;
101
+ // if the stamp is missing/mismatched we can't vouch for it — fall back
102
+ // to the known-good pinned version.
103
+ const expected = readStamp(SHA_STAMP);
104
+ const actual = fileSha256(localPath);
105
+ if (expected && actual === expected) {
106
+ debug(`gsk-mesh cached + verified at ${localPath} (v${installedVersion})`);
107
+ return localPath;
108
+ }
109
+ info(`gsk-mesh: cached v${installedVersion} failed integrity check — ` +
110
+ `re-downloading pinned v${PINNED_VERSION}`);
111
+ }
112
+ else {
113
+ info(`gsk-mesh: cached binary has no version stamp — re-downloading v${PINNED_VERSION}`);
114
+ }
115
+ }
116
+ info(`Downloading gsk-mesh v${PINNED_VERSION} for ${target} …`);
117
+ await downloadAndInstall(cdnUrl(PINNED_VERSION, target), expectedPinned, PINNED_VERSION, target);
118
+ info(`gsk-mesh installed at ${localPath}`);
119
+ return localPath;
120
+ }
121
+ /**
122
+ * Download a specific version+target from `url`, verify its sha256, install it
123
+ * atomically, and update the version/sha stamps. Shared by first-run
124
+ * (`ensureMeshBinary`) and `gsk mesh upgrade` (which passes a newer version).
125
+ */
126
+ export async function downloadAndInstall(url, expectedSha, version, target) {
127
+ fs.mkdirSync(BIN_DIR, { recursive: true });
128
+ const dest = binPath(target);
129
+ await downloadWithProgress(url, dest, expectedSha);
130
+ fs.chmodSync(dest, 0o755);
131
+ await stripQuarantineXattr(dest);
132
+ fs.writeFileSync(VERSION_STAMP, version);
133
+ fs.writeFileSync(SHA_STAMP, expectedSha);
134
+ }
135
+ function downloadWithProgress(url, dest, expectedSha, redirectsLeft = 5) {
136
+ // Temp file + atomic rename so a Ctrl-C mid-download never leaves a partial
137
+ // binary that the next run would treat as valid. The counter suffix keeps
138
+ // concurrent installs (e.g. autorun + foreground) off the same temp path.
139
+ const tmp = `${dest}.tmp.${process.pid}.${_tmpCounter++}`;
140
+ return new Promise((resolve, reject) => {
141
+ const req = https.get(url, res => {
142
+ const status = res.statusCode ?? 0;
143
+ // Follow CDN redirects (301/302/307/308).
144
+ if ([301, 302, 307, 308].includes(status) && res.headers.location) {
145
+ res.resume();
146
+ if (redirectsLeft <= 0) {
147
+ reject(new Error(`Too many redirects fetching gsk-mesh from ${url}`));
148
+ return;
149
+ }
150
+ const next = new URL(res.headers.location, url).toString();
151
+ downloadWithProgress(next, dest, expectedSha, redirectsLeft - 1).then(resolve, reject);
152
+ return;
153
+ }
154
+ if (status !== 200) {
155
+ res.resume();
156
+ reject(new Error(`CDN returned HTTP ${status} for ${url}`));
157
+ return;
158
+ }
159
+ const total = parseInt(res.headers['content-length'] || '0', 10);
160
+ let received = 0;
161
+ let lastPrint = 0;
162
+ const hasher = crypto.createHash('sha256');
163
+ const out = fs.createWriteStream(tmp);
164
+ res.on('data', (chunk) => {
165
+ received += chunk.length;
166
+ hasher.update(chunk);
167
+ const now = Date.now();
168
+ if (now - lastPrint > 50) {
169
+ lastPrint = now;
170
+ const pct = total ? Math.round((received / total) * 100) : 0;
171
+ const mb = (received / (1024 * 1024)).toFixed(1);
172
+ const totalMb = total ? (total / (1024 * 1024)).toFixed(1) : '?';
173
+ process.stderr.write(`\r ${pct}% ${mb} / ${totalMb} MB`);
174
+ }
175
+ });
176
+ res.pipe(out);
177
+ out.on('finish', () => {
178
+ process.stderr.write('\n');
179
+ const actual = hasher.digest('hex');
180
+ if (actual !== expectedSha) {
181
+ try {
182
+ fs.unlinkSync(tmp);
183
+ }
184
+ catch {
185
+ /* best effort */
186
+ }
187
+ reject(new Error(`sha256 mismatch for gsk-mesh:\n expected: ${expectedSha}\n actual: ${actual}`));
188
+ return;
189
+ }
190
+ try {
191
+ fs.renameSync(tmp, dest);
192
+ }
193
+ catch (err) {
194
+ reject(err);
195
+ return;
196
+ }
197
+ resolve();
198
+ });
199
+ out.on('error', reject);
200
+ });
201
+ req.on('error', reject);
202
+ });
203
+ }
204
+ /**
205
+ * Strip macOS's com.apple.quarantine xattr so Gatekeeper doesn't prompt on
206
+ * first launch. The release binaries are Apple-notarized; the prompt is just
207
+ * friction. No-op off macOS, and ignores "no such xattr" when absent.
208
+ */
209
+ function stripQuarantineXattr(file) {
210
+ if (process.platform !== 'darwin')
211
+ return Promise.resolve();
212
+ return new Promise(resolve => {
213
+ const x = spawn('xattr', ['-d', 'com.apple.quarantine', file], { stdio: 'ignore' });
214
+ x.on('exit', () => resolve());
215
+ x.on('error', () => resolve());
216
+ });
217
+ }
218
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/mesh/download.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * gsk-mesh native-binary manifest — pinned version, CDN layout, platform
3
+ * detection, and the sha256 floor table for first-run downloads.
4
+ *
5
+ * ─── CONTRACT (gen-spark#32059) ──────────────────────────────────────────
6
+ * The platform strings produced by `currentTarget()` (and the keys of
7
+ * CHECKSUMS) MUST match, byte-for-byte, the platforms registered in the
8
+ * backend at:
9
+ * backend/voice/update_model.py :: APP_REGISTRY["gsk-mesh"].platforms
10
+ * The backend builds its manifest filename as `{channel}-{platform}.yml` and
11
+ * looks it up against the CLI-supplied `target` string verbatim, so any drift
12
+ * (e.g. "mac-arm64" vs "darwin-arm64", or channel "prerelease" vs "beta")
13
+ * surfaces as a silent 404 / "no update" rather than a typed error.
14
+ *
15
+ * Five targets : darwin-arm64 / darwin-x64 / linux-x64 / linux-arm64 / win-x64
16
+ * Channels : stable / beta (the CLI `--prerelease` flag maps to `beta`)
17
+ * ─────────────────────────────────────────────────────────────────────────
18
+ *
19
+ * PINNED_VERSION + CHECKSUMS are the FLOOR — the version `gsk mesh` pulls on
20
+ * first use. Routine version bumps after npm publish are handled at runtime by
21
+ * `gsk mesh upgrade` (and the autorun check) against the backend endpoint, so
22
+ * we do NOT re-publish @genspark/cli for every gsk-mesh release.
23
+ */
24
+ export declare const PINNED_VERSION = "0.1.2";
25
+ export declare const CDN_BASE = "https://cdn1.genspark.ai/user-upload-image/client/gsk-mesh";
26
+ export type MeshTarget = 'darwin-arm64' | 'darwin-x64' | 'linux-x64' | 'linux-arm64' | 'win-x64';
27
+ /**
28
+ * Map process.platform / process.arch to a gsk-mesh target string.
29
+ * Throws for any platform/arch combination gsk-mesh does not publish.
30
+ */
31
+ export declare function currentTarget(): MeshTarget;
32
+ /** `.exe` on Windows, empty elsewhere. */
33
+ export declare function binExt(target: string): string;
34
+ /** Full CDN download URL for a given version + target. */
35
+ export declare function cdnUrl(version: string, target: string): string;
36
+ /**
37
+ * sha256 of each target's binary at PINNED_VERSION. Populated from the
38
+ * gsk-mesh release's published `.sha256` sidecars at
39
+ * <CDN_BASE>/v<VERSION>/gsk-mesh-<VERSION>-<target>[.exe].sha256
40
+ * (see cli/scripts/sync-mesh-manifest.cjs — runs at prepublishOnly).
41
+ *
42
+ * The KEYS here are the contract surface with the backend (see top-of-file).
43
+ */
44
+ export declare const CHECKSUMS: Record<MeshTarget, string>;
45
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/mesh/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,eAAO,MAAM,cAAc,UAAU,CAAA;AAErC,eAAO,MAAM,QAAQ,+DACyC,CAAA;AAE9D,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,YAAY,GACZ,WAAW,GACX,aAAa,GACb,SAAS,CAAA;AAEb;;;GAGG;AACH,wBAAgB,aAAa,IAAI,UAAU,CA6B1C;AAED,0CAA0C;AAC1C,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAWhD,CAAA"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * gsk-mesh native-binary manifest — pinned version, CDN layout, platform
3
+ * detection, and the sha256 floor table for first-run downloads.
4
+ *
5
+ * ─── CONTRACT (gen-spark#32059) ──────────────────────────────────────────
6
+ * The platform strings produced by `currentTarget()` (and the keys of
7
+ * CHECKSUMS) MUST match, byte-for-byte, the platforms registered in the
8
+ * backend at:
9
+ * backend/voice/update_model.py :: APP_REGISTRY["gsk-mesh"].platforms
10
+ * The backend builds its manifest filename as `{channel}-{platform}.yml` and
11
+ * looks it up against the CLI-supplied `target` string verbatim, so any drift
12
+ * (e.g. "mac-arm64" vs "darwin-arm64", or channel "prerelease" vs "beta")
13
+ * surfaces as a silent 404 / "no update" rather than a typed error.
14
+ *
15
+ * Five targets : darwin-arm64 / darwin-x64 / linux-x64 / linux-arm64 / win-x64
16
+ * Channels : stable / beta (the CLI `--prerelease` flag maps to `beta`)
17
+ * ─────────────────────────────────────────────────────────────────────────
18
+ *
19
+ * PINNED_VERSION + CHECKSUMS are the FLOOR — the version `gsk mesh` pulls on
20
+ * first use. Routine version bumps after npm publish are handled at runtime by
21
+ * `gsk mesh upgrade` (and the autorun check) against the backend endpoint, so
22
+ * we do NOT re-publish @genspark/cli for every gsk-mesh release.
23
+ */
24
+ export const PINNED_VERSION = '0.1.2';
25
+ export const CDN_BASE = 'https://cdn1.genspark.ai/user-upload-image/client/gsk-mesh';
26
+ /**
27
+ * Map process.platform / process.arch to a gsk-mesh target string.
28
+ * Throws for any platform/arch combination gsk-mesh does not publish.
29
+ */
30
+ export function currentTarget() {
31
+ const platform = process.platform === 'darwin'
32
+ ? 'darwin'
33
+ : process.platform === 'win32'
34
+ ? 'win'
35
+ : process.platform === 'linux'
36
+ ? 'linux'
37
+ : null;
38
+ const arch = process.arch === 'arm64' ? 'arm64' : process.arch === 'x64' ? 'x64' : null;
39
+ if (!platform || !arch) {
40
+ throw new Error(`gsk-mesh has no published binary for ${process.platform}/${process.arch}. ` +
41
+ `Supported: ${Object.keys(CHECKSUMS).join(', ')}.`);
42
+ }
43
+ // Windows only ships x64; Windows-on-ARM runs x64 binaries natively via
44
+ // emulation, so map win/arm64 → win-x64 rather than erroring. darwin/linux
45
+ // ship both arches.
46
+ const target = platform === 'win' ? 'win-x64' : `${platform}-${arch}`;
47
+ if (!(target in CHECKSUMS)) {
48
+ throw new Error(`gsk-mesh has no published binary for ${target}. ` +
49
+ `Supported: ${Object.keys(CHECKSUMS).join(', ')}.`);
50
+ }
51
+ return target;
52
+ }
53
+ /** `.exe` on Windows, empty elsewhere. */
54
+ export function binExt(target) {
55
+ return target.startsWith('win-') ? '.exe' : '';
56
+ }
57
+ /** Full CDN download URL for a given version + target. */
58
+ export function cdnUrl(version, target) {
59
+ return `${CDN_BASE}/v${version}/gsk-mesh-${version}-${target}${binExt(target)}`;
60
+ }
61
+ /**
62
+ * sha256 of each target's binary at PINNED_VERSION. Populated from the
63
+ * gsk-mesh release's published `.sha256` sidecars at
64
+ * <CDN_BASE>/v<VERSION>/gsk-mesh-<VERSION>-<target>[.exe].sha256
65
+ * (see cli/scripts/sync-mesh-manifest.cjs — runs at prepublishOnly).
66
+ *
67
+ * The KEYS here are the contract surface with the backend (see top-of-file).
68
+ */
69
+ export const CHECKSUMS = {
70
+ 'darwin-arm64': '8492aaa47d4f513e49fe75ce83c8b46f52f8d70f996cfc1cb007ed4b10362d53',
71
+ 'darwin-x64': '35ddbf4357bdd94d7782c80d0e21288ca6f06fcf79a39303702ae62e06615296',
72
+ 'linux-x64': '40be4437dead5c9be148f3cef626c4c562f92b9949d6be12a86c2da4f92ffccd',
73
+ 'linux-arm64': '6f73cd7aa9c21a82da11724c1099bde109a8b1ed14fe18f4cab6224a9546481f',
74
+ 'win-x64': '254cbfb6bd7b7afcc883ea4b13c824e0906820765156f9d3cdb07b3bf4935ebb',
75
+ };
76
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/mesh/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAA;AAErC,MAAM,CAAC,MAAM,QAAQ,GACnB,4DAA4D,CAAA;AAS9D;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3B,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;gBAC5B,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,IAAI,CAAA;IACd,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;IAEvF,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,wCAAwC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,IAAI;YAC1E,cAAc,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACrD,CAAA;IACH,CAAC;IAED,wEAAwE;IACxE,2EAA2E;IAC3E,oBAAoB;IACpB,MAAM,MAAM,GAAG,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAA;IACrE,IAAI,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,wCAAwC,MAAM,IAAI;YAChD,cAAc,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACrD,CAAA;IACH,CAAC;IACD,OAAO,MAAoB,CAAA;AAC7B,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;AAChD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,MAAc;IACpD,OAAO,GAAG,QAAQ,KAAK,OAAO,aAAa,OAAO,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAA;AACjF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAA+B;IACnD,cAAc,EACZ,kEAAkE;IACpE,YAAY,EACV,kEAAkE;IACpE,WAAW,EACT,kEAAkE;IACpE,aAAa,EACX,kEAAkE;IACpE,SAAS,EACP,kEAAkE;CACrE,CAAA"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * `gsk mesh upgrade` + the throttled autorun currency check.
3
+ *
4
+ * Talks to the backend endpoint added in gen-spark#32059:
5
+ * GET {base}/api/gsk-mesh/checkupdate/{target}?channel=stable|beta
6
+ * &current_version=<installed>
7
+ * → 200 {version, sha256, url, notes} (update available)
8
+ * → 204 (already latest / none promoted)
9
+ *
10
+ * Contract notes:
11
+ * - The CLI `--prerelease` flag maps to channel `beta` (the backend only
12
+ * knows stable/beta; `prerelease` would collapse to stable).
13
+ * - Auth is optional: the autorun check frequently fires unauthenticated, so
14
+ * we send the bearer token when present but never require it.
15
+ */
16
+ export interface UpgradeOptions {
17
+ force?: boolean;
18
+ prerelease?: boolean;
19
+ /**
20
+ * Explicit `--base-url` from the command line (already resolved by the
21
+ * caller). Highest priority — see resolveBaseUrl.
22
+ */
23
+ baseUrlOverride?: string;
24
+ }
25
+ export type UpgradeResult = 'updated' | 'up-to-date' | 'error';
26
+ /**
27
+ * Body of the explicit `gsk mesh upgrade` command.
28
+ * `--force` ignores the installed version (always pulls the channel's latest).
29
+ */
30
+ export declare function runUpgrade(opts: UpgradeOptions): Promise<UpgradeResult>;
31
+ /**
32
+ * Best-effort autorun currency check, invoked (non-awaited) from the `gsk mesh`
33
+ * passthrough path. Only fires when:
34
+ * - autorun isn't disabled (GSK_NO_AUTO_UPDATE / config auto_update:false),
35
+ * - a binary is already installed (never triggers a first download here),
36
+ * - the shared 4h throttle has elapsed.
37
+ * A newer release is downloaded in the background so it applies next run; the
38
+ * current invocation is never blocked or failed by this.
39
+ */
40
+ export declare function maybeAutoUpgradeMesh(baseUrlOverride?: string): Promise<void>;
41
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/mesh/upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,CAAA;AAwE9D;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAiD7E;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsClF"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * `gsk mesh upgrade` + the throttled autorun currency check.
3
+ *
4
+ * Talks to the backend endpoint added in gen-spark#32059:
5
+ * GET {base}/api/gsk-mesh/checkupdate/{target}?channel=stable|beta
6
+ * &current_version=<installed>
7
+ * → 200 {version, sha256, url, notes} (update available)
8
+ * → 204 (already latest / none promoted)
9
+ *
10
+ * Contract notes:
11
+ * - The CLI `--prerelease` flag maps to channel `beta` (the backend only
12
+ * knows stable/beta; `prerelease` would collapse to stable).
13
+ * - Auth is optional: the autorun check frequently fires unauthenticated, so
14
+ * we send the bearer token when present but never require it.
15
+ */
16
+ import { CDN_BASE, currentTarget, } from './manifest.js';
17
+ import { downloadAndInstall, getInstalledMeshVersion, isMeshInstalled, } from './download.js';
18
+ import { loadUpdateMeta, saveUpdateMeta, CHECK_INTERVAL_MS, } from '../updater.js';
19
+ import { info, debug, error as logError } from '../logger.js';
20
+ import { loadConfigFile } from '../config.js';
21
+ /**
22
+ * Resolve the backend base URL the gsk-mesh endpoint is served from.
23
+ *
24
+ * Priority matches the main CLI's getGlobalOptions (CLI flag > env > config),
25
+ * then falls back to PROD rather than gsk's localhost dev default — gsk-mesh
26
+ * binaries + endpoint are production-served.
27
+ */
28
+ function resolveBaseUrl(override) {
29
+ const cfg = loadConfigFile();
30
+ return (override ||
31
+ process.env.GSK_BASE_URL ||
32
+ cfg.base_url ||
33
+ 'https://www.genspark.ai').replace(/\/$/, '');
34
+ }
35
+ /** channel string for the request: --prerelease → beta, else stable. */
36
+ function channelFor(opts) {
37
+ return opts.prerelease ? 'beta' : 'stable';
38
+ }
39
+ /**
40
+ * Query the backend for the latest gsk-mesh release for this target+channel.
41
+ * Returns the manifest (200), null (204 / no update), or throws on transport
42
+ * / HTTP errors.
43
+ */
44
+ async function fetchCheckUpdate(target, channel, currentVersion, baseUrlOverride) {
45
+ const base = resolveBaseUrl(baseUrlOverride);
46
+ const cfg = loadConfigFile();
47
+ const apiKey = cfg.api_key || process.env.GSK_API_KEY;
48
+ const params = new URLSearchParams({ channel });
49
+ if (currentVersion)
50
+ params.set('current_version', currentVersion);
51
+ const url = `${base}/api/gsk-mesh/checkupdate/${target}?${params.toString()}`;
52
+ const headers = {
53
+ // gsk-mesh/<ver> UA lets the backend gatekeeper treat this as client
54
+ // traffic for gradual rollout (gk_gsk_mesh_update).
55
+ 'User-Agent': `gsk-mesh/${currentVersion ?? '0.0.0'}`,
56
+ };
57
+ if (currentVersion)
58
+ headers['gs-version'] = currentVersion;
59
+ if (apiKey)
60
+ headers['Authorization'] = `Bearer ${apiKey}`;
61
+ const controller = new AbortController();
62
+ const timeout = setTimeout(() => controller.abort(), 8000);
63
+ try {
64
+ const resp = await fetch(url, { headers, signal: controller.signal });
65
+ if (resp.status === 204)
66
+ return null;
67
+ if (!resp.ok) {
68
+ throw new Error(`checkupdate HTTP ${resp.status}`);
69
+ }
70
+ return (await resp.json());
71
+ }
72
+ finally {
73
+ clearTimeout(timeout);
74
+ }
75
+ }
76
+ /**
77
+ * Body of the explicit `gsk mesh upgrade` command.
78
+ * `--force` ignores the installed version (always pulls the channel's latest).
79
+ */
80
+ export async function runUpgrade(opts) {
81
+ const target = currentTarget();
82
+ const channel = channelFor(opts);
83
+ const installed = getInstalledMeshVersion();
84
+ // With --force, omit current_version so the backend returns latest
85
+ // regardless of what we have cached.
86
+ const currentForQuery = opts.force ? null : installed;
87
+ let manifest;
88
+ try {
89
+ manifest = await fetchCheckUpdate(target, channel, currentForQuery, opts.baseUrlOverride);
90
+ }
91
+ catch (err) {
92
+ logError(`gsk mesh upgrade: ${err.message}`);
93
+ return 'error';
94
+ }
95
+ // Record the check timestamp regardless of outcome (shared throttle file).
96
+ saveUpdateMeta({
97
+ last_mesh_check: new Date().toISOString(),
98
+ latest_mesh_version: manifest?.version || undefined,
99
+ });
100
+ if (!manifest) {
101
+ info(`gsk-mesh is already at the latest ${channel} release${installed ? ` (v${installed})` : ''}.`);
102
+ return 'up-to-date';
103
+ }
104
+ // --force on the same version: re-pull anyway.
105
+ if (!opts.force && installed && installed === manifest.version) {
106
+ info(`gsk-mesh is already at v${manifest.version} (latest ${channel}).`);
107
+ return 'up-to-date';
108
+ }
109
+ // Defense in depth: the served URL must live under the trusted CDN base.
110
+ if (!manifest.url.startsWith(`${CDN_BASE}/`)) {
111
+ logError(`gsk mesh upgrade: refusing untrusted download URL ${manifest.url}`);
112
+ return 'error';
113
+ }
114
+ info(`gsk-mesh: ${installed ?? '(none)'} → v${manifest.version}`);
115
+ if (manifest.notes)
116
+ info(manifest.notes);
117
+ try {
118
+ await downloadAndInstall(manifest.url, manifest.sha256, manifest.version, target);
119
+ }
120
+ catch (err) {
121
+ logError(`gsk mesh upgrade: ${err.message}`);
122
+ return 'error';
123
+ }
124
+ info(`gsk-mesh upgraded to v${manifest.version}.`);
125
+ return 'updated';
126
+ }
127
+ /**
128
+ * Best-effort autorun currency check, invoked (non-awaited) from the `gsk mesh`
129
+ * passthrough path. Only fires when:
130
+ * - autorun isn't disabled (GSK_NO_AUTO_UPDATE / config auto_update:false),
131
+ * - a binary is already installed (never triggers a first download here),
132
+ * - the shared 4h throttle has elapsed.
133
+ * A newer release is downloaded in the background so it applies next run; the
134
+ * current invocation is never blocked or failed by this.
135
+ */
136
+ export async function maybeAutoUpgradeMesh(baseUrlOverride) {
137
+ try {
138
+ if (process.env.GSK_NO_AUTO_UPDATE === '1')
139
+ return;
140
+ // On Windows a running .exe is locked, so an in-the-background install that
141
+ // renames over the binary just spawned by this same invocation always
142
+ // fails (and wastes the download). Windows currency comes from an explicit
143
+ // `gsk mesh upgrade`, which runs standalone without the binary in use.
144
+ if (process.platform === 'win32')
145
+ return;
146
+ const cfg = loadConfigFile();
147
+ if (cfg.auto_update === false)
148
+ return;
149
+ if (!isMeshInstalled())
150
+ return;
151
+ const meta = loadUpdateMeta();
152
+ if (meta?.last_mesh_check) {
153
+ const elapsed = Date.now() - new Date(meta.last_mesh_check).getTime();
154
+ if (elapsed < CHECK_INTERVAL_MS) {
155
+ debug(`gsk-mesh: skipping autorun check (last ${Math.round(elapsed / 60000)}m ago)`);
156
+ return;
157
+ }
158
+ }
159
+ const target = currentTarget();
160
+ const installed = getInstalledMeshVersion();
161
+ const manifest = await fetchCheckUpdate(target, 'stable', installed, baseUrlOverride);
162
+ saveUpdateMeta({
163
+ last_mesh_check: new Date().toISOString(),
164
+ latest_mesh_version: manifest?.version || undefined,
165
+ });
166
+ if (!manifest || (installed && manifest.version === installed))
167
+ return;
168
+ if (!manifest.url.startsWith(`${CDN_BASE}/`))
169
+ return;
170
+ debug(`gsk-mesh: autorun upgrade ${installed ?? '(none)'} → v${manifest.version}`);
171
+ await downloadAndInstall(manifest.url, manifest.sha256, manifest.version, target);
172
+ info(`gsk-mesh updated to v${manifest.version} (applies next run).`);
173
+ }
174
+ catch (err) {
175
+ // Never surface autorun failures to the user.
176
+ debug(`gsk-mesh autorun check failed: ${err.message}`);
177
+ }
178
+ }
179
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/mesh/upgrade.ts"],"names":[],"mappings":"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"}