@geminilight/mindos 0.1.1 → 0.1.2
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 +3 -1
- package/README_zh.md +3 -1
- package/bin/cli.js +55 -3
- package/mcp/src/index.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,9 +122,11 @@ npm link # registers the `mindos` command globally
|
|
|
122
122
|
### 2. Interactive Setup
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
|
-
mindos onboard --install-daemon
|
|
125
|
+
mindos onboard --install-daemon
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
> `--install-daemon`: after setup, automatically installs and starts MindOS as a background OS service (survives terminal close, auto-restarts on crash).
|
|
129
|
+
|
|
128
130
|
The setup wizard will guide you through:
|
|
129
131
|
1. Knowledge base path → default `~/.mindos/my-mind`
|
|
130
132
|
2. Choose template language (en / zh)
|
package/README_zh.md
CHANGED
|
@@ -122,9 +122,11 @@ npm link # 将 mindos 命令注册为全局命令
|
|
|
122
122
|
### 2. 交互式配置
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
|
-
mindos onboard --install-daemon
|
|
125
|
+
mindos onboard --install-daemon
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
> `--install-daemon`:配置完成后,自动将 MindOS 安装为后台 OS 服务(关闭终端仍运行,崩溃自动重启)。
|
|
129
|
+
|
|
128
130
|
配置向导将引导你完成:
|
|
129
131
|
1. 知识库路径 → 默认 `~/.mindos/my-mind`
|
|
130
132
|
2. 选择模板语言(en / zh / empty)
|
package/bin/cli.js
CHANGED
|
@@ -126,6 +126,19 @@ function clearBuildLock() {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
function ensureAppDeps() {
|
|
130
|
+
// When installed as a global npm package, app/node_modules may not exist.
|
|
131
|
+
// next (and other deps) must be resolvable from app/ for Turbopack to work.
|
|
132
|
+
const appNext = resolve(ROOT, 'app', 'node_modules', 'next', 'package.json');
|
|
133
|
+
if (!existsSync(appNext)) {
|
|
134
|
+
console.log(yellow('Installing app dependencies (first run)...\n'));
|
|
135
|
+
// --no-workspaces: prevent npm from hoisting deps to monorepo root.
|
|
136
|
+
// When globally installed, deps must live in app/node_modules/ so that
|
|
137
|
+
// Turbopack can resolve next/package.json from the app/ project directory.
|
|
138
|
+
run('npm install --prefer-offline --no-workspaces', resolve(ROOT, 'app'));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
129
142
|
// ── Port check ────────────────────────────────────────────────────────────────
|
|
130
143
|
|
|
131
144
|
function isPortInUse(port) {
|
|
@@ -237,8 +250,20 @@ const systemd = {
|
|
|
237
250
|
console.log(green('✔ Service installed and enabled'));
|
|
238
251
|
},
|
|
239
252
|
|
|
240
|
-
start() {
|
|
253
|
+
async start() {
|
|
241
254
|
execSync('systemctl --user start mindos', { stdio: 'inherit' });
|
|
255
|
+
// Wait up to 10s for the service to become active
|
|
256
|
+
const ok = await waitForService(() => {
|
|
257
|
+
try {
|
|
258
|
+
const out = execSync('systemctl --user is-active mindos', { encoding: 'utf-8' }).trim();
|
|
259
|
+
return out === 'active';
|
|
260
|
+
} catch { return false; }
|
|
261
|
+
});
|
|
262
|
+
if (!ok) {
|
|
263
|
+
console.error(red('\n✘ Service failed to start. Last log output:'));
|
|
264
|
+
try { execSync(`journalctl --user -u mindos -n 30 --no-pager`, { stdio: 'inherit' }); } catch {}
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
242
267
|
console.log(green('✔ Service started'));
|
|
243
268
|
},
|
|
244
269
|
|
|
@@ -314,8 +339,20 @@ const launchd = {
|
|
|
314
339
|
console.log(green('✔ Service installed'));
|
|
315
340
|
},
|
|
316
341
|
|
|
317
|
-
start() {
|
|
342
|
+
async start() {
|
|
318
343
|
execSync(`launchctl kickstart -k gui/${launchctlUid()}/${LAUNCHD_LABEL}`, { stdio: 'inherit' });
|
|
344
|
+
// Wait up to 10s for the service to become active
|
|
345
|
+
const ok = await waitForService(() => {
|
|
346
|
+
try {
|
|
347
|
+
const out = execSync(`launchctl print gui/${launchctlUid()}/${LAUNCHD_LABEL}`, { encoding: 'utf-8' });
|
|
348
|
+
return out.includes('state = running');
|
|
349
|
+
} catch { return false; }
|
|
350
|
+
});
|
|
351
|
+
if (!ok) {
|
|
352
|
+
console.error(red('\n✘ Service failed to start. Last log output:'));
|
|
353
|
+
try { execSync(`tail -n 30 ${LOG_PATH}`, { stdio: 'inherit' }); } catch {}
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
319
356
|
console.log(green('✔ Service started'));
|
|
320
357
|
},
|
|
321
358
|
|
|
@@ -352,6 +389,14 @@ const launchd = {
|
|
|
352
389
|
|
|
353
390
|
// ── gateway dispatcher ────────────────────────────────────────────────────────
|
|
354
391
|
|
|
392
|
+
async function waitForService(check, { retries = 10, intervalMs = 1000 } = {}) {
|
|
393
|
+
for (let i = 0; i < retries; i++) {
|
|
394
|
+
if (check()) return true;
|
|
395
|
+
await new Promise(r => setTimeout(r, intervalMs));
|
|
396
|
+
}
|
|
397
|
+
return check();
|
|
398
|
+
}
|
|
399
|
+
|
|
355
400
|
async function runGatewayCommand(sub) {
|
|
356
401
|
const platform = getPlatform();
|
|
357
402
|
if (!platform) {
|
|
@@ -396,7 +441,11 @@ function printStartupInfo(webPort, mcpPort) {
|
|
|
396
441
|
console.log(`\n${'─'.repeat(53)}`);
|
|
397
442
|
console.log(`${bold('🧠 MindOS is starting')}\n`);
|
|
398
443
|
console.log(` ${green('●')} Web UI ${cyan(`http://localhost:${webPort}`)}`);
|
|
399
|
-
console.log(`
|
|
444
|
+
if (localIP) console.log(` ${cyan(`http://${localIP}:${webPort}`)}`);
|
|
445
|
+
console.log(` ${green('●')} MCP ${cyan(`http://localhost:${mcpPort}/mcp`)}`);
|
|
446
|
+
if (localIP) console.log(` ${cyan(`http://${localIP}:${mcpPort}/mcp`)}`);
|
|
447
|
+
if (localIP) console.log(dim(`\n 💡 Running on a remote server? Open the Network URL (${localIP}) in your browser,\n or use SSH port forwarding: ssh -L ${webPort}:localhost:${webPort} user@${localIP}`));
|
|
448
|
+
console.log();
|
|
400
449
|
console.log(bold('Configure MCP in your Agent:'));
|
|
401
450
|
console.log(dim(' Local (same machine):'));
|
|
402
451
|
console.log(block('localhost'));
|
|
@@ -481,6 +530,7 @@ const commands = {
|
|
|
481
530
|
const mcpPort = process.env.MINDOS_MCP_PORT || '8787';
|
|
482
531
|
await assertPortFree(Number(webPort), 'web');
|
|
483
532
|
await assertPortFree(Number(mcpPort), 'mcp');
|
|
533
|
+
ensureAppDeps();
|
|
484
534
|
const mcp = spawnMcp(isVerbose);
|
|
485
535
|
savePids(process.pid, mcp.pid);
|
|
486
536
|
process.on('exit', clearPids);
|
|
@@ -514,6 +564,7 @@ const commands = {
|
|
|
514
564
|
const mcpPort = process.env.MINDOS_MCP_PORT || '8787';
|
|
515
565
|
await assertPortFree(Number(webPort), 'web');
|
|
516
566
|
await assertPortFree(Number(mcpPort), 'mcp');
|
|
567
|
+
ensureAppDeps();
|
|
517
568
|
if (needsBuild()) {
|
|
518
569
|
console.log(yellow('Building MindOS (first run or new version detected)...\n'));
|
|
519
570
|
clearBuildLock();
|
|
@@ -529,6 +580,7 @@ const commands = {
|
|
|
529
580
|
|
|
530
581
|
// ── build ──────────────────────────────────────────────────────────────────
|
|
531
582
|
build: () => {
|
|
583
|
+
ensureAppDeps();
|
|
532
584
|
clearBuildLock();
|
|
533
585
|
run(`npx next build ${extra}`, resolve(ROOT, 'app'));
|
|
534
586
|
writeBuildStamp();
|
package/mcp/src/index.ts
CHANGED
|
@@ -470,7 +470,8 @@ async function main() {
|
|
|
470
470
|
}
|
|
471
471
|
|
|
472
472
|
expressApp.all(MCP_ENDPOINT, async (req, res) => {
|
|
473
|
-
|
|
473
|
+
// Pass pre-parsed body: express.json() already parsed it, SDK >= 1.7 expects it as 3rd arg
|
|
474
|
+
await transport.handleRequest(req, res, req.body);
|
|
474
475
|
});
|
|
475
476
|
|
|
476
477
|
await server.connect(transport);
|
package/package.json
CHANGED