@geminilight/mindos 0.5.39 → 0.5.41
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/app/next-env.d.ts +1 -1
- package/bin/cli.js +79 -5
- package/bin/lib/gateway.js +40 -3
- package/package.json +1 -1
package/app/next-env.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="next" />
|
|
2
2
|
/// <reference types="next/image-types/global" />
|
|
3
|
-
import "./.next/types/routes.d.ts";
|
|
3
|
+
import "./.next/dev/types/routes.d.ts";
|
|
4
4
|
|
|
5
5
|
// NOTE: This file should not be edited
|
|
6
6
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
package/bin/cli.js
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
41
|
import { execSync } from 'node:child_process';
|
|
42
|
-
import { existsSync, readFileSync, writeFileSync, rmSync,
|
|
42
|
+
import { existsSync, readFileSync, writeFileSync, rmSync, cpSync } from 'node:fs';
|
|
43
43
|
import { resolve } from 'node:path';
|
|
44
44
|
import { homedir } from 'node:os';
|
|
45
45
|
|
|
@@ -50,7 +50,7 @@ import { bold, dim, cyan, green, red, yellow } from './lib/colors.js';
|
|
|
50
50
|
const NEXT_BIN = resolve(ROOT, 'app', 'node_modules', '.bin', 'next');
|
|
51
51
|
import { run, npmInstall } from './lib/utils.js';
|
|
52
52
|
import { loadConfig, getStartMode, isDaemonMode } from './lib/config.js';
|
|
53
|
-
import { needsBuild, writeBuildStamp,
|
|
53
|
+
import { needsBuild, writeBuildStamp, cleanNextDir, ensureAppDeps } from './lib/build.js';
|
|
54
54
|
import { isPortInUse, assertPortFree } from './lib/port.js';
|
|
55
55
|
import { savePids, clearPids } from './lib/pid.js';
|
|
56
56
|
import { stopMindos } from './lib/stop.js';
|
|
@@ -60,6 +60,72 @@ import { spawnMcp } from './lib/mcp-spawn.js';
|
|
|
60
60
|
import { mcpInstall } from './lib/mcp-install.js';
|
|
61
61
|
import { initSync, startSyncDaemon, stopSyncDaemon, getSyncStatus, manualSync, listConflicts, setSyncEnabled } from './lib/sync.js';
|
|
62
62
|
|
|
63
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Dynamically resolve the new ROOT after `npm install -g`.
|
|
67
|
+
* This is needed because constants are evaluated at module load time.
|
|
68
|
+
*/
|
|
69
|
+
function getUpdatedRoot() {
|
|
70
|
+
try {
|
|
71
|
+
const mindosBin = execSync('which mindos', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
72
|
+
if (mindosBin) {
|
|
73
|
+
// mindos bin is usually at <root>/bin/cli.js or a symlink to it
|
|
74
|
+
let cliPath;
|
|
75
|
+
try {
|
|
76
|
+
cliPath = execSync(`readlink -f "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
77
|
+
} catch {
|
|
78
|
+
try {
|
|
79
|
+
cliPath = execSync(`realpath "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
80
|
+
} catch {
|
|
81
|
+
cliPath = mindosBin;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (cliPath) {
|
|
85
|
+
// cliPath is like /path/to/node_modules/@geminilight/mindos/bin/cli.js
|
|
86
|
+
// ROOT is /path/to/node_modules/@geminilight/mindos
|
|
87
|
+
return resolve(dirname(cliPath), '..');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch {}
|
|
91
|
+
// Fallback to static ROOT
|
|
92
|
+
return ROOT;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Build the app in the given root if the build stamp doesn't match the package version.
|
|
97
|
+
* Used by `mindos update` to pre-build before restarting the daemon.
|
|
98
|
+
*/
|
|
99
|
+
function buildIfNeeded(newRoot) {
|
|
100
|
+
const newBuildStamp = resolve(newRoot, 'app', '.next', '.mindos-build-version');
|
|
101
|
+
const newNextBin = resolve(newRoot, 'app', 'node_modules', '.bin', 'next');
|
|
102
|
+
|
|
103
|
+
let needBuild = true;
|
|
104
|
+
try {
|
|
105
|
+
const builtVersion = readFileSync(newBuildStamp, 'utf-8').trim();
|
|
106
|
+
const pkgVersion = JSON.parse(readFileSync(resolve(newRoot, 'package.json'), 'utf-8')).version;
|
|
107
|
+
needBuild = builtVersion !== pkgVersion;
|
|
108
|
+
} catch {
|
|
109
|
+
needBuild = true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!needBuild) return;
|
|
113
|
+
|
|
114
|
+
console.log(yellow('\n Building MindOS (version change detected)...\n'));
|
|
115
|
+
const appPkg = resolve(newRoot, 'app', 'package.json');
|
|
116
|
+
if (existsSync(appPkg)) {
|
|
117
|
+
run('npm install', resolve(newRoot, 'app'));
|
|
118
|
+
}
|
|
119
|
+
const nextDir = resolve(newRoot, 'app', '.next');
|
|
120
|
+
if (existsSync(nextDir)) {
|
|
121
|
+
run(`rm -rf "${nextDir}"`, newRoot);
|
|
122
|
+
}
|
|
123
|
+
run('node scripts/gen-renderer-index.js', newRoot);
|
|
124
|
+
run(`${newNextBin} build`, resolve(newRoot, 'app'));
|
|
125
|
+
const version = JSON.parse(readFileSync(resolve(newRoot, 'package.json'), 'utf-8')).version;
|
|
126
|
+
writeFileSync(newBuildStamp, version, 'utf-8');
|
|
127
|
+
}
|
|
128
|
+
|
|
63
129
|
// ── Commands ──────────────────────────────────────────────────────────────────
|
|
64
130
|
|
|
65
131
|
const cmd = process.argv[2];
|
|
@@ -665,8 +731,13 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
|
|
|
665
731
|
}
|
|
666
732
|
|
|
667
733
|
if (daemonRunning) {
|
|
668
|
-
console.log(cyan('\n Daemon is running —
|
|
734
|
+
console.log(cyan('\n Daemon is running — stopping to apply the new version...'));
|
|
669
735
|
await runGatewayCommand('stop');
|
|
736
|
+
|
|
737
|
+
// After npm install -g, resolve the new installation path and pre-build
|
|
738
|
+
const newRoot = getUpdatedRoot();
|
|
739
|
+
buildIfNeeded(newRoot);
|
|
740
|
+
|
|
670
741
|
await runGatewayCommand('install');
|
|
671
742
|
// install() starts the service:
|
|
672
743
|
// - systemd: daemon-reload + enable + start
|
|
@@ -694,13 +765,16 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
|
|
|
694
765
|
process.exit(1);
|
|
695
766
|
}
|
|
696
767
|
} else {
|
|
768
|
+
// Non-daemon mode: build in foreground for better UX
|
|
769
|
+
buildIfNeeded(getUpdatedRoot());
|
|
770
|
+
|
|
697
771
|
console.log(`\n${green('✔')} ${bold(`Updated: ${currentVersion} → ${newVersion}`)}`);
|
|
698
|
-
console.log(dim(' Run `mindos start`
|
|
772
|
+
console.log(dim(' Run `mindos start` to start the updated version.'));
|
|
699
773
|
console.log(` ${dim('View changelog:')} ${cyan('https://github.com/GeminiLight/MindOS/releases')}\n`);
|
|
700
774
|
}
|
|
701
775
|
},
|
|
702
776
|
|
|
703
|
-
// ── uninstall
|
|
777
|
+
// ── uninstall ───────────────────────────────────────────────────────────────
|
|
704
778
|
uninstall: async () => {
|
|
705
779
|
const readline = await import('node:readline');
|
|
706
780
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
package/bin/lib/gateway.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync, statSync, renameSync, unlinkSync, openSync, readSync, closeSync } from 'node:fs';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { MINDOS_DIR, LOG_PATH, CLI_PATH, NODE_BIN, CONFIG_PATH } from './constants.js';
|
|
6
6
|
import { green, red, dim, cyan, yellow } from './colors.js';
|
|
@@ -8,6 +8,41 @@ import { isPortInUse } from './port.js';
|
|
|
8
8
|
|
|
9
9
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Dynamically resolve the current mindos CLI path.
|
|
13
|
+
* This is needed because CLI_PATH is evaluated at module load time,
|
|
14
|
+
* but after `npm install -g @geminilight/mindos@latest`, the path may have changed.
|
|
15
|
+
*/
|
|
16
|
+
function getCurrentCliPath() {
|
|
17
|
+
try {
|
|
18
|
+
// Try to find mindos in PATH
|
|
19
|
+
const mindosBin = execSync('which mindos', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
20
|
+
if (mindosBin) {
|
|
21
|
+
// mindos is usually a symlink, resolve it
|
|
22
|
+
try {
|
|
23
|
+
const realPath = execSync(`readlink -f "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
24
|
+
if (realPath && existsSync(realPath)) {
|
|
25
|
+
return realPath;
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
// readlink -f not available on macOS, fallback to realpath
|
|
29
|
+
try {
|
|
30
|
+
const realPath = execSync(`realpath "${mindosBin}"`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
|
|
31
|
+
if (realPath && existsSync(realPath)) {
|
|
32
|
+
return realPath;
|
|
33
|
+
}
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
// Fallback: use the symlink target itself
|
|
37
|
+
if (existsSync(mindosBin)) {
|
|
38
|
+
return mindosBin;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} catch {}
|
|
42
|
+
// Fallback to static CLI_PATH if dynamic resolution fails
|
|
43
|
+
return CLI_PATH;
|
|
44
|
+
}
|
|
45
|
+
|
|
11
46
|
/** Rotate log file when it exceeds 2 MB. Keeps at most one .old backup. */
|
|
12
47
|
function rotateLogs() {
|
|
13
48
|
try {
|
|
@@ -169,6 +204,7 @@ const systemd = {
|
|
|
169
204
|
ensureMindosDir();
|
|
170
205
|
rotateLogs();
|
|
171
206
|
const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
|
|
207
|
+
const cliPath = getCurrentCliPath();
|
|
172
208
|
const unit = [
|
|
173
209
|
'[Unit]',
|
|
174
210
|
'Description=MindOS app + MCP server',
|
|
@@ -176,7 +212,7 @@ const systemd = {
|
|
|
176
212
|
'',
|
|
177
213
|
'[Service]',
|
|
178
214
|
'Type=simple',
|
|
179
|
-
`ExecStart=${NODE_BIN} ${
|
|
215
|
+
`ExecStart=${NODE_BIN} ${cliPath} start`,
|
|
180
216
|
'Restart=on-failure',
|
|
181
217
|
'RestartSec=3',
|
|
182
218
|
`Environment=HOME=${homedir()}`,
|
|
@@ -253,6 +289,7 @@ const launchd = {
|
|
|
253
289
|
ensureMindosDir();
|
|
254
290
|
rotateLogs();
|
|
255
291
|
const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
|
|
292
|
+
const cliPath = getCurrentCliPath();
|
|
256
293
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
257
294
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
258
295
|
<plist version="1.0">
|
|
@@ -261,7 +298,7 @@ const launchd = {
|
|
|
261
298
|
<key>ProgramArguments</key>
|
|
262
299
|
<array>
|
|
263
300
|
<string>${NODE_BIN}</string>
|
|
264
|
-
<string>${
|
|
301
|
+
<string>${cliPath}</string>
|
|
265
302
|
<string>start</string>
|
|
266
303
|
</array>
|
|
267
304
|
<key>RunAtLoad</key><true/>
|
package/package.json
CHANGED