@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 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 # setup + install & start as background OS service
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(` ${green('●')} MCP ${cyan(`http://localhost:${mcpPort}/mcp`)}\n`);
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
- await transport.handleRequest(req, res);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MindOS — Human-Agent Collaborative Mind System. Local-first knowledge base that syncs your mind to all AI Agents via MCP.",
5
5
  "keywords": [
6
6
  "mindos",