@geminilight/mindos 0.5.11 → 0.5.12
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 +9 -9
- package/README_zh.md +9 -9
- package/app/README.md +2 -2
- package/app/app/api/ask/route.ts +126 -3
- package/app/app/api/mcp/install/route.ts +1 -1
- package/app/app/api/mcp/status/route.ts +1 -1
- package/app/app/api/settings/route.ts +1 -1
- package/app/app/api/setup/route.ts +7 -7
- package/app/app/api/sync/route.ts +21 -16
- package/app/components/AskModal.tsx +28 -21
- package/app/components/ask/MessageList.tsx +62 -3
- package/app/components/ask/ToolCallBlock.tsx +89 -0
- package/app/components/setup/StepReview.tsx +31 -25
- package/app/components/setup/index.tsx +6 -3
- package/app/lib/agent/prompt.ts +32 -0
- package/app/lib/agent/stream-consumer.ts +178 -0
- package/app/lib/agent/tools.ts +122 -0
- package/app/lib/types.ts +18 -0
- package/app/next-env.d.ts +1 -1
- package/app/package.json +2 -2
- package/bin/cli.js +41 -21
- package/bin/lib/gateway.js +24 -3
- package/bin/lib/mcp-install.js +2 -2
- package/bin/lib/mcp-spawn.js +3 -3
- package/bin/lib/stop.js +1 -1
- package/mcp/README.md +5 -5
- package/mcp/src/index.ts +2 -2
- package/package.json +1 -1
- package/scripts/setup.js +12 -12
- package/scripts/upgrade-prompt.md +6 -6
package/bin/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ import { needsBuild, writeBuildStamp, clearBuildLock, cleanNextDir, ensureAppDep
|
|
|
50
50
|
import { isPortInUse, assertPortFree } from './lib/port.js';
|
|
51
51
|
import { savePids, clearPids } from './lib/pid.js';
|
|
52
52
|
import { stopMindos } from './lib/stop.js';
|
|
53
|
-
import { getPlatform, ensureMindosDir, waitForHttp, runGatewayCommand } from './lib/gateway.js';
|
|
53
|
+
import { getPlatform, ensureMindosDir, waitForHttp, waitForPortFree, runGatewayCommand } from './lib/gateway.js';
|
|
54
54
|
import { printStartupInfo, getLocalIP } from './lib/startup.js';
|
|
55
55
|
import { spawnMcp } from './lib/mcp-spawn.js';
|
|
56
56
|
import { mcpInstall } from './lib/mcp-install.js';
|
|
@@ -84,7 +84,7 @@ const commands = {
|
|
|
84
84
|
// ── open ───────────────────────────────────────────────────────────────────
|
|
85
85
|
open: () => {
|
|
86
86
|
loadConfig();
|
|
87
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
87
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
88
88
|
const url = `http://localhost:${webPort}`;
|
|
89
89
|
let cmd;
|
|
90
90
|
if (process.platform === 'darwin') {
|
|
@@ -121,7 +121,7 @@ const commands = {
|
|
|
121
121
|
console.log(dim('No auth token set. Run `mindos onboard` to configure one.'));
|
|
122
122
|
process.exit(0);
|
|
123
123
|
}
|
|
124
|
-
const mcpPort = config.mcpPort ||
|
|
124
|
+
const mcpPort = config.mcpPort || 8781;
|
|
125
125
|
const localIP = getLocalIP();
|
|
126
126
|
|
|
127
127
|
const localUrl = `http://localhost:${mcpPort}/mcp`;
|
|
@@ -197,8 +197,8 @@ const commands = {
|
|
|
197
197
|
// ── dev ────────────────────────────────────────────────────────────────────
|
|
198
198
|
dev: async () => {
|
|
199
199
|
loadConfig();
|
|
200
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
201
|
-
const mcpPort = process.env.MINDOS_MCP_PORT || '
|
|
200
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
201
|
+
const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
|
|
202
202
|
await assertPortFree(Number(webPort), 'web');
|
|
203
203
|
await assertPortFree(Number(mcpPort), 'mcp');
|
|
204
204
|
ensureAppDeps();
|
|
@@ -231,11 +231,13 @@ const commands = {
|
|
|
231
231
|
console.warn(yellow('Warning: daemon mode not supported on this platform. Falling back to foreground.'));
|
|
232
232
|
} else {
|
|
233
233
|
loadConfig();
|
|
234
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
235
|
-
const mcpPort = process.env.MINDOS_MCP_PORT || '
|
|
234
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
235
|
+
const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
|
|
236
236
|
console.log(cyan(`Installing MindOS as a background service (${platform})...`));
|
|
237
237
|
await runGatewayCommand('install');
|
|
238
|
-
|
|
238
|
+
// install() already starts the service via launchctl bootstrap + RunAtLoad=true.
|
|
239
|
+
// Do NOT call start() here — kickstart -k would kill the just-started process,
|
|
240
|
+
// causing a port-conflict race condition with KeepAlive restart loops.
|
|
239
241
|
console.log(dim(' (First run may take a few minutes to install dependencies and build the app.)'));
|
|
240
242
|
console.log(dim(' Follow live progress with: mindos logs\n'));
|
|
241
243
|
const ready = await waitForHttp(Number(webPort), { retries: 120, intervalMs: 2000, label: 'Web UI' });
|
|
@@ -261,10 +263,26 @@ const commands = {
|
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
loadConfig();
|
|
264
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
265
|
-
const mcpPort = process.env.MINDOS_MCP_PORT || '
|
|
266
|
-
|
|
267
|
-
|
|
266
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
267
|
+
const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
|
|
268
|
+
|
|
269
|
+
// When launched by a daemon manager (launchd/systemd), wait for ports to
|
|
270
|
+
// free instead of exiting immediately — the previous instance may still be
|
|
271
|
+
// shutting down after a restart/update.
|
|
272
|
+
const launchedByDaemon = process.env.LAUNCHED_BY_LAUNCHD === '1'
|
|
273
|
+
|| !!process.env.INVOCATION_ID; /* systemd sets INVOCATION_ID */
|
|
274
|
+
|
|
275
|
+
if (launchedByDaemon) {
|
|
276
|
+
const webOk = await waitForPortFree(Number(webPort), { retries: 60, intervalMs: 500 });
|
|
277
|
+
const mcpOk = await waitForPortFree(Number(mcpPort), { retries: 60, intervalMs: 500 });
|
|
278
|
+
if (!webOk || !mcpOk) {
|
|
279
|
+
console.error('Ports still in use after 30s, exiting.');
|
|
280
|
+
process.exit(1); // KeepAlive will retry after ThrottleInterval
|
|
281
|
+
}
|
|
282
|
+
} else {
|
|
283
|
+
await assertPortFree(Number(webPort), 'web');
|
|
284
|
+
await assertPortFree(Number(mcpPort), 'mcp');
|
|
285
|
+
}
|
|
268
286
|
ensureAppDeps();
|
|
269
287
|
if (needsBuild()) {
|
|
270
288
|
console.log(yellow('Building MindOS (first run or new version detected)...\n'));
|
|
@@ -306,8 +324,8 @@ const commands = {
|
|
|
306
324
|
run('npm install --prefer-offline --no-workspaces', resolve(ROOT, 'mcp'));
|
|
307
325
|
}
|
|
308
326
|
// Map config env vars to what the MCP server expects
|
|
309
|
-
const mcpPort = process.env.MINDOS_MCP_PORT || '
|
|
310
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
327
|
+
const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
|
|
328
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
311
329
|
process.env.MCP_PORT = mcpPort;
|
|
312
330
|
process.env.MINDOS_URL = `http://localhost:${webPort}`;
|
|
313
331
|
run(`npx tsx src/index.ts`, resolve(ROOT, 'mcp'));
|
|
@@ -328,8 +346,8 @@ const commands = {
|
|
|
328
346
|
loadConfig();
|
|
329
347
|
|
|
330
348
|
// After loadConfig, env vars reflect the NEW config (or old if unchanged).
|
|
331
|
-
const newWebPort = Number(process.env.MINDOS_WEB_PORT || '
|
|
332
|
-
const newMcpPort = Number(process.env.MINDOS_MCP_PORT || '
|
|
349
|
+
const newWebPort = Number(process.env.MINDOS_WEB_PORT || '3456');
|
|
350
|
+
const newMcpPort = Number(process.env.MINDOS_MCP_PORT || '8781');
|
|
333
351
|
|
|
334
352
|
// Collect old ports that differ from new ones — processes may still be
|
|
335
353
|
// listening there even though config already points to the new ports.
|
|
@@ -465,8 +483,8 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
|
|
|
465
483
|
}
|
|
466
484
|
|
|
467
485
|
// 6. Ports
|
|
468
|
-
const webPort = Number(config?.port || process.env.MINDOS_WEB_PORT ||
|
|
469
|
-
const mcpPort = Number(config?.mcpPort || process.env.MINDOS_MCP_PORT ||
|
|
486
|
+
const webPort = Number(config?.port || process.env.MINDOS_WEB_PORT || 3456);
|
|
487
|
+
const mcpPort = Number(config?.mcpPort || process.env.MINDOS_MCP_PORT || 8781);
|
|
470
488
|
const webInUse = await isPortInUse(webPort);
|
|
471
489
|
const mcpInUse = await isPortInUse(mcpPort);
|
|
472
490
|
if (webInUse) {
|
|
@@ -582,11 +600,13 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
|
|
|
582
600
|
console.log(cyan('\n Daemon is running — restarting to apply the new version...'));
|
|
583
601
|
await runGatewayCommand('stop');
|
|
584
602
|
await runGatewayCommand('install');
|
|
585
|
-
|
|
603
|
+
// Note: install() already starts the service via launchctl bootstrap + RunAtLoad=true.
|
|
604
|
+
// Do NOT call start() here — kickstart -k would kill the just-started process,
|
|
605
|
+
// causing a port-conflict race condition with KeepAlive restart loops.
|
|
586
606
|
const webPort = (() => {
|
|
587
|
-
try { return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')).port ??
|
|
607
|
+
try { return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')).port ?? 3456; } catch { return 3456; }
|
|
588
608
|
})();
|
|
589
|
-
console.log(dim(' (Waiting for Web UI to come back up...)'));
|
|
609
|
+
console.log(dim(' (Waiting for Web UI to come back up — first run after update includes a rebuild...)'));
|
|
590
610
|
const ready = await waitForHttp(Number(webPort), { retries: 120, intervalMs: 2000, label: 'Web UI' });
|
|
591
611
|
if (ready) {
|
|
592
612
|
console.log(green('✔ MindOS restarted and ready.\n'));
|
package/bin/lib/gateway.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync, statSync, renameSync, unlinkSync } from 'node:fs';
|
|
3
3
|
import { resolve } 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';
|
|
@@ -8,6 +8,18 @@ import { isPortInUse } from './port.js';
|
|
|
8
8
|
|
|
9
9
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
10
10
|
|
|
11
|
+
/** Rotate log file when it exceeds 2 MB. Keeps at most one .old backup. */
|
|
12
|
+
function rotateLogs() {
|
|
13
|
+
try {
|
|
14
|
+
const stat = statSync(LOG_PATH);
|
|
15
|
+
if (stat.size > 2 * 1024 * 1024) {
|
|
16
|
+
const old = LOG_PATH + '.old';
|
|
17
|
+
try { unlinkSync(old); } catch {}
|
|
18
|
+
renameSync(LOG_PATH, old);
|
|
19
|
+
}
|
|
20
|
+
} catch { /* file doesn't exist yet, nothing to rotate */ }
|
|
21
|
+
}
|
|
22
|
+
|
|
11
23
|
export function getPlatform() {
|
|
12
24
|
if (process.platform === 'darwin') return 'launchd';
|
|
13
25
|
if (process.platform === 'linux') return 'systemd';
|
|
@@ -72,6 +84,7 @@ const systemd = {
|
|
|
72
84
|
install() {
|
|
73
85
|
if (!existsSync(SYSTEMD_DIR)) mkdirSync(SYSTEMD_DIR, { recursive: true });
|
|
74
86
|
ensureMindosDir();
|
|
87
|
+
rotateLogs();
|
|
75
88
|
const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
|
|
76
89
|
const unit = [
|
|
77
90
|
'[Unit]',
|
|
@@ -100,6 +113,7 @@ const systemd = {
|
|
|
100
113
|
},
|
|
101
114
|
|
|
102
115
|
async start() {
|
|
116
|
+
rotateLogs();
|
|
103
117
|
execSync('systemctl --user start mindos', { stdio: 'inherit' });
|
|
104
118
|
const ok = await waitForService(() => {
|
|
105
119
|
try {
|
|
@@ -153,6 +167,7 @@ const launchd = {
|
|
|
153
167
|
install() {
|
|
154
168
|
if (!existsSync(LAUNCHD_DIR)) mkdirSync(LAUNCHD_DIR, { recursive: true });
|
|
155
169
|
ensureMindosDir();
|
|
170
|
+
rotateLogs();
|
|
156
171
|
const currentPath = process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin';
|
|
157
172
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
158
173
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -166,13 +181,18 @@ const launchd = {
|
|
|
166
181
|
<string>start</string>
|
|
167
182
|
</array>
|
|
168
183
|
<key>RunAtLoad</key><true/>
|
|
169
|
-
<key>KeepAlive</key
|
|
184
|
+
<key>KeepAlive</key>
|
|
185
|
+
<dict>
|
|
186
|
+
<key>SuccessfulExit</key><false/>
|
|
187
|
+
</dict>
|
|
188
|
+
<key>ThrottleInterval</key><integer>5</integer>
|
|
170
189
|
<key>StandardOutPath</key><string>${LOG_PATH}</string>
|
|
171
190
|
<key>StandardErrorPath</key><string>${LOG_PATH}</string>
|
|
172
191
|
<key>EnvironmentVariables</key>
|
|
173
192
|
<dict>
|
|
174
193
|
<key>HOME</key><string>${homedir()}</string>
|
|
175
194
|
<key>PATH</key><string>${currentPath}</string>
|
|
195
|
+
<key>LAUNCHED_BY_LAUNCHD</key><string>1</string>
|
|
176
196
|
</dict>
|
|
177
197
|
</dict>
|
|
178
198
|
</plist>
|
|
@@ -192,6 +212,7 @@ const launchd = {
|
|
|
192
212
|
},
|
|
193
213
|
|
|
194
214
|
async start() {
|
|
215
|
+
rotateLogs();
|
|
195
216
|
execSync(`launchctl kickstart -k gui/${launchctlUid()}/${LAUNCHD_LABEL}`, { stdio: 'inherit' });
|
|
196
217
|
const ok = await waitForService(() => {
|
|
197
218
|
try {
|
|
@@ -209,7 +230,7 @@ const launchd = {
|
|
|
209
230
|
|
|
210
231
|
async stop() {
|
|
211
232
|
// Read ports before bootout so we can wait for them to be freed
|
|
212
|
-
let webPort =
|
|
233
|
+
let webPort = 3456, mcpPort = 8781;
|
|
213
234
|
try {
|
|
214
235
|
const config = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
215
236
|
if (config.port) webPort = Number(config.port);
|
package/bin/lib/mcp-install.js
CHANGED
|
@@ -253,8 +253,8 @@ export async function mcpInstall() {
|
|
|
253
253
|
const ask2 = (q) => new Promise(r => rl2.question(q, r));
|
|
254
254
|
|
|
255
255
|
if (!url) {
|
|
256
|
-
let mcpPort =
|
|
257
|
-
try { mcpPort = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')).mcpPort ||
|
|
256
|
+
let mcpPort = 8781;
|
|
257
|
+
try { mcpPort = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')).mcpPort || 8781; } catch {}
|
|
258
258
|
const defaultUrl = `http://localhost:${mcpPort}/mcp`;
|
|
259
259
|
url = hasYesFlag ? defaultUrl : (await ask2(`${bold('MCP URL')} ${dim(`[${defaultUrl}]:`)} `)).trim() || defaultUrl;
|
|
260
260
|
}
|
package/bin/lib/mcp-spawn.js
CHANGED
|
@@ -5,8 +5,8 @@ import { ROOT } from './constants.js';
|
|
|
5
5
|
import { bold, red, yellow } from './colors.js';
|
|
6
6
|
|
|
7
7
|
export function spawnMcp(verbose = false) {
|
|
8
|
-
const mcpPort = process.env.MINDOS_MCP_PORT || '
|
|
9
|
-
const webPort = process.env.MINDOS_WEB_PORT || '
|
|
8
|
+
const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
|
|
9
|
+
const webPort = process.env.MINDOS_WEB_PORT || '3456';
|
|
10
10
|
// Ensure mcp/node_modules exists (auto-install on first run)
|
|
11
11
|
const mcpSdk = resolve(ROOT, 'mcp', 'node_modules', '@modelcontextprotocol', 'sdk', 'package.json');
|
|
12
12
|
if (!existsSync(mcpSdk)) {
|
|
@@ -16,7 +16,7 @@ export function spawnMcp(verbose = false) {
|
|
|
16
16
|
const env = {
|
|
17
17
|
...process.env,
|
|
18
18
|
MCP_PORT: mcpPort,
|
|
19
|
-
MINDOS_URL: `http://
|
|
19
|
+
MINDOS_URL: process.env.MINDOS_URL || `http://127.0.0.1:${webPort}`,
|
|
20
20
|
...(verbose ? { MCP_VERBOSE: '1' } : {}),
|
|
21
21
|
};
|
|
22
22
|
const child = spawn('npx', ['tsx', 'src/index.ts'], {
|
package/bin/lib/stop.js
CHANGED
|
@@ -75,7 +75,7 @@ function killTree(pid) {
|
|
|
75
75
|
*/
|
|
76
76
|
export function stopMindos(opts = {}) {
|
|
77
77
|
// Read ports from config for port-based cleanup
|
|
78
|
-
let webPort = '
|
|
78
|
+
let webPort = '3456', mcpPort = '8781';
|
|
79
79
|
try {
|
|
80
80
|
const config = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
81
81
|
if (config.port) webPort = String(config.port);
|
package/mcp/README.md
CHANGED
|
@@ -26,7 +26,7 @@ mindos start # starts app + MCP server together
|
|
|
26
26
|
Or run MCP server only:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
mindos mcp # HTTP mode (default, port
|
|
29
|
+
mindos mcp # HTTP mode (default, port 8781)
|
|
30
30
|
MCP_TRANSPORT=stdio mindos mcp # stdio mode
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -34,11 +34,11 @@ MCP_TRANSPORT=stdio mindos mcp # stdio mode
|
|
|
34
34
|
|
|
35
35
|
| Variable | Default | Description |
|
|
36
36
|
|----------|---------|-------------|
|
|
37
|
-
| `MINDOS_URL` | `http://localhost:
|
|
37
|
+
| `MINDOS_URL` | `http://localhost:3456` | App server base URL |
|
|
38
38
|
| `AUTH_TOKEN` | — | Optional: bearer token (must match App's `AUTH_TOKEN`) |
|
|
39
39
|
| `MCP_TRANSPORT` | `http` | Transport mode: `http` or `stdio` |
|
|
40
40
|
| `MCP_HOST` | `127.0.0.1` | HTTP bind address (`0.0.0.0` for remote access) |
|
|
41
|
-
| `MCP_PORT` | `
|
|
41
|
+
| `MCP_PORT` | `8781` | HTTP listen port (configurable via `mindos onboard`) |
|
|
42
42
|
| `MCP_ENDPOINT` | `/mcp` | HTTP endpoint path |
|
|
43
43
|
|
|
44
44
|
## MCP Tools (20)
|
|
@@ -75,7 +75,7 @@ Add to your Agent's MCP config (field names vary by client):
|
|
|
75
75
|
{
|
|
76
76
|
"mcpServers": {
|
|
77
77
|
"mindos": {
|
|
78
|
-
"url": "http://localhost:
|
|
78
|
+
"url": "http://localhost:8781/mcp",
|
|
79
79
|
"headers": { "Authorization": "Bearer your-token" }
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -101,7 +101,7 @@ Add to your Agent's MCP config (field names vary by client):
|
|
|
101
101
|
{
|
|
102
102
|
"mcpServers": {
|
|
103
103
|
"mindos": {
|
|
104
|
-
"url": "http://<server-ip>:
|
|
104
|
+
"url": "http://<server-ip>:8781/mcp",
|
|
105
105
|
"headers": { "Authorization": "Bearer your-token" }
|
|
106
106
|
}
|
|
107
107
|
}
|
package/mcp/src/index.ts
CHANGED
|
@@ -22,11 +22,11 @@ import { z } from "zod";
|
|
|
22
22
|
|
|
23
23
|
// ─── Config ──────────────────────────────────────────────────────────────────
|
|
24
24
|
|
|
25
|
-
const BASE_URL = process.env.MINDOS_URL ?? "http://localhost:
|
|
25
|
+
const BASE_URL = process.env.MINDOS_URL ?? "http://localhost:3456";
|
|
26
26
|
const AUTH_TOKEN = process.env.AUTH_TOKEN;
|
|
27
27
|
const MCP_TRANSPORT = process.env.MCP_TRANSPORT ?? "http"; // "http" | "stdio"
|
|
28
28
|
const MCP_HOST = process.env.MCP_HOST ?? "127.0.0.1";
|
|
29
|
-
const MCP_PORT = parseInt(process.env.MCP_PORT ?? "
|
|
29
|
+
const MCP_PORT = parseInt(process.env.MCP_PORT ?? "8781", 10);
|
|
30
30
|
const MCP_ENDPOINT = process.env.MCP_ENDPOINT ?? "/mcp";
|
|
31
31
|
const CHARACTER_LIMIT = 25_000;
|
|
32
32
|
|
package/package.json
CHANGED
package/scripts/setup.js
CHANGED
|
@@ -844,11 +844,11 @@ async function startGuiSetup() {
|
|
|
844
844
|
if (isFirstTime) {
|
|
845
845
|
// First-time onboard: use a temporary port (scan from 9100) so the user's
|
|
846
846
|
// chosen port in Step 3 can differ without a mid-setup restart.
|
|
847
|
-
// 9100 is chosen to avoid conflicts with common services (5000=AirPlay,
|
|
847
|
+
// 9100 is chosen to avoid conflicts with common services (5000=AirPlay, 3456/8080=dev).
|
|
848
848
|
usePort = await findFreePort(9100);
|
|
849
849
|
} else {
|
|
850
850
|
// Re-onboard: service is already running on config.port — reuse it.
|
|
851
|
-
const existingPort = config.port ||
|
|
851
|
+
const existingPort = config.port || 3456;
|
|
852
852
|
if (await isSelfPort(existingPort)) {
|
|
853
853
|
// Service already running — just open the setup page, no need to spawn.
|
|
854
854
|
const url = `http://localhost:${existingPort}/setup`;
|
|
@@ -866,7 +866,7 @@ async function startGuiSetup() {
|
|
|
866
866
|
// stopMindos() sends SIGTERM synchronously — wait for both web and mcp
|
|
867
867
|
// ports to free, since `start` will assertPortFree on both.
|
|
868
868
|
const { waitForPortFree } = await import('../bin/lib/gateway.js');
|
|
869
|
-
const mcpPort = config.mcpPort ||
|
|
869
|
+
const mcpPort = config.mcpPort || 8781;
|
|
870
870
|
const [webFreed, mcpFreed] = await Promise.all([
|
|
871
871
|
waitForPortFree(existingPort),
|
|
872
872
|
waitForPortFree(mcpPort),
|
|
@@ -941,8 +941,8 @@ async function main() {
|
|
|
941
941
|
|
|
942
942
|
console.log(c.bold('\nExisting config:'));
|
|
943
943
|
console.log(row('Knowledge base:', c.cyan(existing.mindRoot || '(not set)')));
|
|
944
|
-
console.log(row('Web port:', c.cyan(String(existing.port || '
|
|
945
|
-
console.log(row('MCP port:', c.cyan(String(existing.mcpPort || '
|
|
944
|
+
console.log(row('Web port:', c.cyan(String(existing.port || '3456'))));
|
|
945
|
+
console.log(row('MCP port:', c.cyan(String(existing.mcpPort || '8781'))));
|
|
946
946
|
console.log(row('Auth token:', existing.authToken ? mask(existing.authToken) : c.dim('(not set)')));
|
|
947
947
|
console.log(row('Web password:', existing.webPassword ? '••••••••' : c.dim('(none)')));
|
|
948
948
|
console.log(row('AI provider:', c.cyan(existing.ai?.provider || '(not set)')));
|
|
@@ -953,7 +953,7 @@ async function main() {
|
|
|
953
953
|
const overwrite = await askYesNo('cfgExists', CONFIG_PATH);
|
|
954
954
|
if (!overwrite) {
|
|
955
955
|
const existingMode = existing.startMode || 'start';
|
|
956
|
-
const existingMcpPort = existing.mcpPort ||
|
|
956
|
+
const existingMcpPort = existing.mcpPort || 8781;
|
|
957
957
|
const existingAuth = existing.authToken || '';
|
|
958
958
|
const existingMindRoot = existing.mindRoot || resolve(homedir(), 'MindOS', 'mind');
|
|
959
959
|
console.log(`\n${c.green(t('cfgKept'))} ${c.dim(CONFIG_PATH)}`);
|
|
@@ -1072,8 +1072,8 @@ async function main() {
|
|
|
1072
1072
|
write('\n');
|
|
1073
1073
|
stepHeader(3);
|
|
1074
1074
|
const existingCfg = resumeCfg;
|
|
1075
|
-
const defaultWebPort = typeof existingCfg.port === 'number' ? existingCfg.port :
|
|
1076
|
-
const defaultMcpPort = typeof existingCfg.mcpPort === 'number' ? existingCfg.mcpPort : (defaultWebPort ===
|
|
1075
|
+
const defaultWebPort = typeof existingCfg.port === 'number' ? existingCfg.port : 3456;
|
|
1076
|
+
const defaultMcpPort = typeof existingCfg.mcpPort === 'number' ? existingCfg.mcpPort : (defaultWebPort === 8781 ? 8782 : 8781);
|
|
1077
1077
|
let webPort, mcpPort;
|
|
1078
1078
|
while (true) {
|
|
1079
1079
|
webPort = await askPort('webPortPrompt', defaultWebPort);
|
|
@@ -1178,8 +1178,8 @@ async function main() {
|
|
|
1178
1178
|
|
|
1179
1179
|
const isResuming = Object.keys(resumeCfg).length > 0;
|
|
1180
1180
|
const needsRestart = isResuming && (
|
|
1181
|
-
config.port !== (resumeCfg.port ??
|
|
1182
|
-
config.mcpPort !== (resumeCfg.mcpPort ??
|
|
1181
|
+
config.port !== (resumeCfg.port ?? 3456) ||
|
|
1182
|
+
config.mcpPort !== (resumeCfg.mcpPort ?? 8781) ||
|
|
1183
1183
|
config.mindRoot !== (resumeCfg.mindRoot ?? '') ||
|
|
1184
1184
|
config.authToken !== (resumeCfg.authToken ?? '') ||
|
|
1185
1185
|
config.webPassword !== (resumeCfg.webPassword ?? '')
|
|
@@ -1212,7 +1212,7 @@ async function main() {
|
|
|
1212
1212
|
}
|
|
1213
1213
|
|
|
1214
1214
|
const installDaemon = startMode === 'daemon' || process.argv.includes('--install-daemon');
|
|
1215
|
-
finish(mindDir, config.startMode, config.mcpPort, config.authToken, installDaemon, needsRestart, resumeCfg.port ??
|
|
1215
|
+
finish(mindDir, config.startMode, config.mcpPort, config.authToken, installDaemon, needsRestart, resumeCfg.port ?? 3456);
|
|
1216
1216
|
}
|
|
1217
1217
|
|
|
1218
1218
|
function getLocalIP() {
|
|
@@ -1224,7 +1224,7 @@ function getLocalIP() {
|
|
|
1224
1224
|
return null;
|
|
1225
1225
|
}
|
|
1226
1226
|
|
|
1227
|
-
async function finish(mindDir, startMode = 'start', mcpPort =
|
|
1227
|
+
async function finish(mindDir, startMode = 'start', mcpPort = 8781, authToken = '', installDaemon = false, needsRestart = false, oldPort = 3456) {
|
|
1228
1228
|
if (needsRestart) {
|
|
1229
1229
|
const isRunning = await isSelfPort(oldPort);
|
|
1230
1230
|
if (isRunning) {
|
|
@@ -37,8 +37,8 @@ Help me upgrade my MindOS installation from the old source-based setup to the ne
|
|
|
37
37
|
```json
|
|
38
38
|
{
|
|
39
39
|
"mindRoot": "<value of MIND_ROOT>",
|
|
40
|
-
"port":
|
|
41
|
-
"mcpPort":
|
|
40
|
+
"port": 3456,
|
|
41
|
+
"mcpPort": 8781,
|
|
42
42
|
"authToken": "<value of AUTH_TOKEN or empty string>",
|
|
43
43
|
"webPassword": "",
|
|
44
44
|
"ai": {
|
|
@@ -69,7 +69,7 @@ Help me upgrade my MindOS installation from the old source-based setup to the ne
|
|
|
69
69
|
```
|
|
70
70
|
(First run will build automatically — this may take a minute.)
|
|
71
71
|
|
|
72
|
-
7. **Confirm** the app is accessible at http://localhost:
|
|
72
|
+
7. **Confirm** the app is accessible at http://localhost:3456 and MCP is running at http://localhost:8781/mcp.
|
|
73
73
|
|
|
74
74
|
Do not delete the old cloned repository — keep it as a backup. The `app/.env.local` file can also be kept as reference.
|
|
75
75
|
```
|
|
@@ -109,8 +109,8 @@ Do not delete the old cloned repository — keep it as a backup. The `app/.env.l
|
|
|
109
109
|
```json
|
|
110
110
|
{
|
|
111
111
|
"mindRoot": "<MIND_ROOT 的值>",
|
|
112
|
-
"port":
|
|
113
|
-
"mcpPort":
|
|
112
|
+
"port": 3456,
|
|
113
|
+
"mcpPort": 8781,
|
|
114
114
|
"authToken": "<AUTH_TOKEN 的值,没有则留空字符串>",
|
|
115
115
|
"webPassword": "",
|
|
116
116
|
"ai": {
|
|
@@ -141,7 +141,7 @@ Do not delete the old cloned repository — keep it as a backup. The `app/.env.l
|
|
|
141
141
|
```
|
|
142
142
|
(首次运行会自动构建,可能需要一两分钟。)
|
|
143
143
|
|
|
144
|
-
7. **确认** http://localhost:
|
|
144
|
+
7. **确认** http://localhost:3456 可以访问,http://localhost:8781/mcp 的 MCP 服务也在运行。
|
|
145
145
|
|
|
146
146
|
不要删除旧的克隆仓库,保留作为备份。`app/.env.local` 也可以保留作参考。
|
|
147
147
|
```
|