mobygate 0.3.0 → 0.4.0
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/CHANGELOG.md +26 -0
- package/bin/mobygate.js +88 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ All notable changes to mobygate are documented here. Format loosely follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version numbers are
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.4.0] — 2026-04-19
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`mobygate update` command** — upgrades to the latest version and
|
|
12
|
+
restarts the service in one step. Detects the install mode:
|
|
13
|
+
- `npm install -g` install → `npm install -g mobygate@latest`
|
|
14
|
+
- git clone → `git pull --ff-only` + `npm install`
|
|
15
|
+
After the update lands, reloads the managed service (launchd /
|
|
16
|
+
Task Scheduler / systemd) so the new code is actually running.
|
|
17
|
+
Aliased as `mobygate upgrade`. Exits early with a friendly message
|
|
18
|
+
if you're already on the latest version.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- `installed_version` in `~/.mobygate/state.json` was hardcoded to
|
|
23
|
+
`"0.1.0"` for every install regardless of the actual version. Now
|
|
24
|
+
read from `package.json` so `mobygate version` and the dashboard
|
|
25
|
+
don't lie about what's running. Also records `install_mode`
|
|
26
|
+
(`git` | `npm` | `unknown`) in the state file.
|
|
27
|
+
- `mobygate version` output now also shows install mode + path, so
|
|
28
|
+
you can tell at a glance whether a machine is running the git
|
|
29
|
+
clone or the npm install.
|
|
30
|
+
- Three duplicated `readFileSync(package.json)` call sites
|
|
31
|
+
collapsed into one `readPackage()` helper in bin/mobygate.js.
|
|
32
|
+
|
|
7
33
|
## [0.3.0] — 2026-04-19
|
|
8
34
|
|
|
9
35
|
Shippable on npm. Sessions survive restarts. Logs live in a canonical
|
package/bin/mobygate.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
22
|
-
import { resolve, dirname, join } from 'path';
|
|
22
|
+
import { resolve, dirname, join, sep } from 'path';
|
|
23
23
|
import { fileURLToPath } from 'url';
|
|
24
24
|
import { spawnSync } from 'child_process';
|
|
25
25
|
import { createInterface } from 'readline';
|
|
@@ -44,6 +44,21 @@ const REPO_ROOT = resolve(dirname(__filename), '..');
|
|
|
44
44
|
const SERVER_LABEL = 'ai.mobygate.server';
|
|
45
45
|
const AUTH_LABEL = 'ai.mobygate.auth-refresh';
|
|
46
46
|
|
|
47
|
+
/** Read this package's metadata once. Version is the single source of truth
|
|
48
|
+
* for banners, state.json, and version comparisons — no more hardcoded
|
|
49
|
+
* strings drifting from package.json. */
|
|
50
|
+
function readPackage() {
|
|
51
|
+
return JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8'));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Detect how mobygate is installed. Matters for `update` routing —
|
|
55
|
+
* git clones pull; npm-globals `npm install -g`. */
|
|
56
|
+
function detectInstallMode() {
|
|
57
|
+
if (existsSync(join(REPO_ROOT, '.git'))) return 'git';
|
|
58
|
+
if (REPO_ROOT.includes(`${sep}node_modules${sep}mobygate`)) return 'npm';
|
|
59
|
+
return 'unknown';
|
|
60
|
+
}
|
|
61
|
+
|
|
47
62
|
// ---------- tiny helpers ----------
|
|
48
63
|
|
|
49
64
|
const c = {
|
|
@@ -80,7 +95,7 @@ async function confirm(q, def = true) {
|
|
|
80
95
|
// ---------- commands ----------
|
|
81
96
|
|
|
82
97
|
async function cmdInit() {
|
|
83
|
-
const pkg =
|
|
98
|
+
const pkg = readPackage();
|
|
84
99
|
print(banner({ version: pkg.version }));
|
|
85
100
|
section('mobygate init');
|
|
86
101
|
print(c.dim(`Platform: ${PLATFORM} Install path: ${REPO_ROOT}`));
|
|
@@ -210,7 +225,8 @@ async function cmdInit() {
|
|
|
210
225
|
|
|
211
226
|
writeState({
|
|
212
227
|
install_path: REPO_ROOT,
|
|
213
|
-
installed_version:
|
|
228
|
+
installed_version: pkg.version,
|
|
229
|
+
install_mode: detectInstallMode(),
|
|
214
230
|
installed_at: new Date().toISOString(),
|
|
215
231
|
platform: PLATFORM,
|
|
216
232
|
node_bin: nodeBin,
|
|
@@ -284,7 +300,7 @@ function cmdRestart() {
|
|
|
284
300
|
}
|
|
285
301
|
|
|
286
302
|
async function cmdStatus() {
|
|
287
|
-
const pkg =
|
|
303
|
+
const pkg = readPackage();
|
|
288
304
|
print(compactBanner({ version: pkg.version }));
|
|
289
305
|
section('mobygate status');
|
|
290
306
|
const config = loadConfig();
|
|
@@ -388,8 +404,70 @@ async function cmdUninstall() {
|
|
|
388
404
|
}
|
|
389
405
|
|
|
390
406
|
function cmdVersion() {
|
|
391
|
-
const pkg =
|
|
392
|
-
print(`mobygate v${pkg.version}`);
|
|
407
|
+
const pkg = readPackage();
|
|
408
|
+
print(`mobygate v${pkg.version} · ${detectInstallMode()} install at ${REPO_ROOT}`);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Upgrade mobygate to the latest version from its source of truth:
|
|
413
|
+
* - `npm` mode → `npm install -g mobygate@latest`
|
|
414
|
+
* - `git` mode → `git pull` + `npm install`
|
|
415
|
+
* After the update lands, restart the service so the running process
|
|
416
|
+
* picks up the new code.
|
|
417
|
+
*/
|
|
418
|
+
async function cmdUpdate() {
|
|
419
|
+
const pkg = readPackage();
|
|
420
|
+
const mode = detectInstallMode();
|
|
421
|
+
section('mobygate update');
|
|
422
|
+
print(c.dim(`Current: v${pkg.version} · ${mode} install at ${REPO_ROOT}`));
|
|
423
|
+
|
|
424
|
+
// ---- Look up latest published version on npm
|
|
425
|
+
info('Checking npm for the latest release...');
|
|
426
|
+
const view = spawnSync('npm', ['view', 'mobygate', 'version'], { encoding: 'utf8', timeout: 10_000 });
|
|
427
|
+
if (view.status !== 0) {
|
|
428
|
+
return die(`Couldn't reach npm registry: ${view.stderr?.trim() || view.error?.message || 'unknown'}`);
|
|
429
|
+
}
|
|
430
|
+
const latest = view.stdout.trim();
|
|
431
|
+
print(c.dim(`Latest: v${latest}`));
|
|
432
|
+
if (latest === pkg.version) {
|
|
433
|
+
return ok(`Already on v${latest}. Nothing to do.`);
|
|
434
|
+
}
|
|
435
|
+
print('');
|
|
436
|
+
|
|
437
|
+
// ---- Perform the upgrade
|
|
438
|
+
if (mode === 'npm') {
|
|
439
|
+
info(`Running \`npm install -g mobygate@latest\`...`);
|
|
440
|
+
const r = spawnSync('npm', ['install', '-g', 'mobygate@latest'], { stdio: 'inherit' });
|
|
441
|
+
if (r.status !== 0) return die('npm install failed. See output above.');
|
|
442
|
+
ok(`Installed mobygate@${latest}`);
|
|
443
|
+
} else if (mode === 'git') {
|
|
444
|
+
info(`Running \`git pull\` in ${REPO_ROOT}...`);
|
|
445
|
+
const pull = spawnSync('git', ['-C', REPO_ROOT, 'pull', '--ff-only'], { stdio: 'inherit' });
|
|
446
|
+
if (pull.status !== 0) return die('git pull failed. Resolve conflicts and retry.');
|
|
447
|
+
info(`Running \`npm install\`...`);
|
|
448
|
+
const install = spawnSync('npm', ['install'], { cwd: REPO_ROOT, stdio: 'inherit' });
|
|
449
|
+
if (install.status !== 0) return die('npm install failed. See output above.');
|
|
450
|
+
ok(`Pulled and installed. See git log for what changed.`);
|
|
451
|
+
} else {
|
|
452
|
+
return die(`Install mode is "${mode}" — can't auto-update. Reinstall via npm or git.`);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ---- Restart the managed service so the new code is running
|
|
456
|
+
section('Restart');
|
|
457
|
+
info('Restarting service so the new build is running...');
|
|
458
|
+
if (IS_MAC) {
|
|
459
|
+
const p = plistPathForLabel(SERVER_LABEL);
|
|
460
|
+
launchctlUnload(p); launchctlLoad(p);
|
|
461
|
+
ok(`Reloaded ${SERVER_LABEL}`);
|
|
462
|
+
} else if (IS_WIN) {
|
|
463
|
+
stopWindowsTask(WIN_LABELS.server); startWindowsTask(WIN_LABELS.server);
|
|
464
|
+
ok(`Restarted ${WIN_LABELS.server}`);
|
|
465
|
+
} else if (IS_LINUX) {
|
|
466
|
+
stopLinuxUnit(LINUX_UNITS.server); startLinuxUnit(LINUX_UNITS.server);
|
|
467
|
+
ok(`Restarted ${LINUX_UNITS.server}`);
|
|
468
|
+
}
|
|
469
|
+
print('');
|
|
470
|
+
info(`Tip: if the install-layout changed (new service file, new paths), run \`mobygate init\` to re-install the service definitions.`);
|
|
393
471
|
}
|
|
394
472
|
|
|
395
473
|
function usage() {
|
|
@@ -397,6 +475,7 @@ function usage() {
|
|
|
397
475
|
|
|
398
476
|
Usage:
|
|
399
477
|
mobygate init Interactive setup: config, services, smoke test
|
|
478
|
+
mobygate update Upgrade to the latest version + restart service
|
|
400
479
|
mobygate start Start the proxy service
|
|
401
480
|
mobygate stop Stop the proxy service
|
|
402
481
|
mobygate restart Stop + start
|
|
@@ -404,7 +483,7 @@ Usage:
|
|
|
404
483
|
mobygate logs Tail the server log
|
|
405
484
|
mobygate auth Show auth status + run a refresh probe
|
|
406
485
|
mobygate uninstall Remove installed services
|
|
407
|
-
mobygate version Print version
|
|
486
|
+
mobygate version Print version + install mode + path
|
|
408
487
|
|
|
409
488
|
Config: ~/.mobygate/config.yaml (env vars override)
|
|
410
489
|
Repo: ${REPO_ROOT}
|
|
@@ -416,6 +495,8 @@ Repo: ${REPO_ROOT}
|
|
|
416
495
|
const cmd = process.argv[2];
|
|
417
496
|
const COMMANDS = {
|
|
418
497
|
init: cmdInit,
|
|
498
|
+
update: cmdUpdate,
|
|
499
|
+
upgrade: cmdUpdate,
|
|
419
500
|
start: cmdStart,
|
|
420
501
|
stop: cmdStop,
|
|
421
502
|
restart: cmdRestart,
|