@genspark/cli 1.0.19 → 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.
- package/README.md +41 -0
- package/dist/commands/mesh.d.ts +40 -0
- package/dist/commands/mesh.d.ts.map +1 -0
- package/dist/commands/mesh.js +164 -0
- package/dist/commands/mesh.js.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/mesh/download.d.ts +35 -0
- package/dist/mesh/download.d.ts.map +1 -0
- package/dist/mesh/download.js +218 -0
- package/dist/mesh/download.js.map +1 -0
- package/dist/mesh/manifest.d.ts +45 -0
- package/dist/mesh/manifest.d.ts.map +1 -0
- package/dist/mesh/manifest.js +76 -0
- package/dist/mesh/manifest.js.map +1 -0
- package/dist/mesh/upgrade.d.ts +41 -0
- package/dist/mesh/upgrade.d.ts.map +1 -0
- package/dist/mesh/upgrade.js +179 -0
- package/dist/mesh/upgrade.js.map +1 -0
- package/dist/updater.d.ts +21 -0
- package/dist/updater.d.ts.map +1 -1
- package/dist/updater.js +18 -4
- package/dist/updater.js.map +1 -1
- package/package.json +4 -2
- package/skills/gsk-inbox-contacts/SKILL.md +40 -0
|
@@ -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
|
+
* ¤t_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
|
+
* ¤t_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":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,QAAQ,EACR,aAAa,GAEd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,GAChB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,iBAAiB,GAClB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAqB7C;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,QAAiB;IACvC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAA;IAC5B,OAAO,CACL,QAAQ;QACR,OAAO,CAAC,GAAG,CAAC,YAAY;QACxB,GAAG,CAAC,QAAQ;QACZ,yBAAyB,CAC1B,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AACtB,CAAC;AAED,wEAAwE;AACxE,SAAS,UAAU,CAAC,IAAoB;IACtC,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC5C,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,gBAAgB,CAC7B,MAAkB,EAClB,OAA0B,EAC1B,cAA6B,EAC7B,eAAwB;IAExB,MAAM,IAAI,GAAG,cAAc,CAAC,eAAe,CAAC,CAAA;IAC5C,MAAM,GAAG,GAAG,cAAc,EAAE,CAAA;IAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAA;IAErD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAC/C,IAAI,cAAc;QAAE,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAA;IACjE,MAAM,GAAG,GAAG,GAAG,IAAI,6BAA6B,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAA;IAE7E,MAAM,OAAO,GAA2B;QACtC,qEAAqE;QACrE,oDAAoD;QACpD,YAAY,EAAE,YAAY,cAAc,IAAI,OAAO,EAAE;KACtD,CAAA;IACD,IAAI,cAAc;QAAE,OAAO,CAAC,YAAY,CAAC,GAAG,cAAc,CAAA;IAC1D,IAAI,MAAM;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAA;IAEzD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;IAC1D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;QACrE,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QACpC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACpD,CAAC;QACD,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAwB,CAAA;IACnD,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAC9B,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAChC,MAAM,SAAS,GAAG,uBAAuB,EAAE,CAAA;IAC3C,mEAAmE;IACnE,qCAAqC;IACrC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IAErD,IAAI,QAAoC,CAAA;IACxC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,CAAA;IAC3F,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QACvD,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,2EAA2E;IAC3E,cAAc,CAAC;QACb,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACzC,mBAAmB,EAAE,QAAQ,EAAE,OAAO,IAAI,SAAS;KACpD,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,IAAI,CAAC,qCAAqC,OAAO,WAAW,SAAS,CAAC,CAAC,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACnG,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,+CAA+C;IAC/C,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,IAAI,SAAS,KAAK,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC/D,IAAI,CAAC,2BAA2B,QAAQ,CAAC,OAAO,YAAY,OAAO,IAAI,CAAC,CAAA;QACxE,OAAO,YAAY,CAAA;IACrB,CAAC;IAED,yEAAyE;IACzE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC7C,QAAQ,CAAC,qDAAqD,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAA;QAC7E,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,IAAI,CAAC,aAAa,SAAS,IAAI,QAAQ,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACjE,IAAI,QAAQ,CAAC,KAAK;QAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACxC,IAAI,CAAC;QACH,MAAM,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACnF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QACvD,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,IAAI,CAAC,yBAAyB,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAA;IAClD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,eAAwB;IACjE,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG;YAAE,OAAM;QAClD,4EAA4E;QAC5E,sEAAsE;QACtE,2EAA2E;QAC3E,uEAAuE;QACvE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAM;QACxC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAA;QAC5B,IAAI,GAAG,CAAC,WAAW,KAAK,KAAK;YAAE,OAAM;QACrC,IAAI,CAAC,eAAe,EAAE;YAAE,OAAM;QAE9B,MAAM,IAAI,GAAG,cAAc,EAAE,CAAA;QAC7B,IAAI,IAAI,EAAE,eAAe,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAA;YACrE,IAAI,OAAO,GAAG,iBAAiB,EAAE,CAAC;gBAChC,KAAK,CAAC,0CAA0C,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;gBACpF,OAAM;YACR,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;QAC9B,MAAM,SAAS,GAAG,uBAAuB,EAAE,CAAA;QAC3C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,CAAC,CAAA;QACrF,cAAc,CAAC;YACb,eAAe,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACzC,mBAAmB,EAAE,QAAQ,EAAE,OAAO,IAAI,SAAS;SACpD,CAAC,CAAA;QACF,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,CAAC;YAAE,OAAM;QACtE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;YAAE,OAAM;QAEpD,KAAK,CAAC,6BAA6B,SAAS,IAAI,QAAQ,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;QAClF,MAAM,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QACjF,IAAI,CAAC,wBAAwB,QAAQ,CAAC,OAAO,sBAAsB,CAAC,CAAA;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8CAA8C;QAC9C,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IACnE,CAAC;AACH,CAAC"}
|
package/dist/updater.d.ts
CHANGED
|
@@ -7,6 +7,27 @@
|
|
|
7
7
|
* - "auto_update": false in config file
|
|
8
8
|
* - Checks at most once every 4 hours (cached in ~/.genspark-tool-cli/update-meta.json)
|
|
9
9
|
*/
|
|
10
|
+
export declare const CHECK_INTERVAL_MS: number;
|
|
11
|
+
/**
|
|
12
|
+
* Shared update bookkeeping for both the npm self-update (last_check /
|
|
13
|
+
* latest_version) and the native gsk-mesh binary (last_mesh_check /
|
|
14
|
+
* latest_mesh_version, written by src/mesh/upgrade.ts). One file, independent
|
|
15
|
+
* throttles — so the mesh autorun check piggybacks on this 4h cadence instead
|
|
16
|
+
* of running its own separate timer.
|
|
17
|
+
*/
|
|
18
|
+
export interface UpdateMeta {
|
|
19
|
+
last_check?: string;
|
|
20
|
+
latest_version?: string;
|
|
21
|
+
last_mesh_check?: string;
|
|
22
|
+
latest_mesh_version?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function loadUpdateMeta(): UpdateMeta | null;
|
|
25
|
+
/**
|
|
26
|
+
* Merge-preserving write: callers pass only the keys they own (npm side vs
|
|
27
|
+
* mesh side), and untouched keys on disk are preserved. A plain overwrite
|
|
28
|
+
* would let the npm check clobber the mesh fields and vice-versa.
|
|
29
|
+
*/
|
|
30
|
+
export declare function saveUpdateMeta(patch: Partial<UpdateMeta>): void;
|
|
10
31
|
/**
|
|
11
32
|
* Check for updates and auto-install if a newer version is available.
|
|
12
33
|
* Safe to call — failures never block CLI execution.
|
package/dist/updater.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"updater.d.ts","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAgBD,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CAOlD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAkB/D;AA4CD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
|