@geminilight/mindos 0.5.21 → 0.5.23

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.
Files changed (60) hide show
  1. package/app/app/api/ask/route.ts +31 -9
  2. package/app/app/api/bootstrap/route.ts +1 -0
  3. package/app/app/api/monitoring/route.ts +95 -0
  4. package/app/app/globals.css +14 -0
  5. package/app/app/setup/page.tsx +3 -2
  6. package/app/components/ActivityBar.tsx +183 -0
  7. package/app/components/AskFab.tsx +39 -97
  8. package/app/components/AskModal.tsx +13 -371
  9. package/app/components/Breadcrumb.tsx +4 -4
  10. package/app/components/FileTree.tsx +21 -4
  11. package/app/components/Logo.tsx +39 -0
  12. package/app/components/Panel.tsx +152 -0
  13. package/app/components/RightAskPanel.tsx +72 -0
  14. package/app/components/SettingsModal.tsx +9 -235
  15. package/app/components/SidebarLayout.tsx +426 -12
  16. package/app/components/SyncStatusBar.tsx +74 -53
  17. package/app/components/TableOfContents.tsx +4 -2
  18. package/app/components/ask/AskContent.tsx +418 -0
  19. package/app/components/ask/MessageList.tsx +2 -2
  20. package/app/components/panels/AgentsPanel.tsx +231 -0
  21. package/app/components/panels/PanelHeader.tsx +35 -0
  22. package/app/components/panels/PluginsPanel.tsx +106 -0
  23. package/app/components/panels/SearchPanel.tsx +178 -0
  24. package/app/components/panels/SyncPopover.tsx +105 -0
  25. package/app/components/renderers/csv/TableView.tsx +4 -4
  26. package/app/components/settings/AgentsTab.tsx +240 -0
  27. package/app/components/settings/AiTab.tsx +39 -1
  28. package/app/components/settings/KnowledgeTab.tsx +116 -2
  29. package/app/components/settings/McpTab.tsx +6 -6
  30. package/app/components/settings/MonitoringTab.tsx +202 -0
  31. package/app/components/settings/SettingsContent.tsx +343 -0
  32. package/app/components/settings/types.ts +1 -1
  33. package/app/components/setup/index.tsx +2 -23
  34. package/app/hooks/useResizeDrag.ts +78 -0
  35. package/app/instrumentation.ts +7 -2
  36. package/app/lib/agent/log.ts +1 -0
  37. package/app/lib/agent/model.ts +33 -10
  38. package/app/lib/api.ts +12 -3
  39. package/app/lib/core/csv.ts +2 -1
  40. package/app/lib/core/fs-ops.ts +7 -6
  41. package/app/lib/core/index.ts +1 -1
  42. package/app/lib/core/lines.ts +7 -6
  43. package/app/lib/core/search-index.ts +174 -0
  44. package/app/lib/core/search.ts +30 -1
  45. package/app/lib/core/security.ts +6 -3
  46. package/app/lib/errors.ts +108 -0
  47. package/app/lib/format.ts +19 -0
  48. package/app/lib/fs.ts +6 -3
  49. package/app/lib/i18n-en.ts +49 -6
  50. package/app/lib/i18n-zh.ts +48 -5
  51. package/app/lib/metrics.ts +81 -0
  52. package/app/next-env.d.ts +1 -1
  53. package/app/next.config.ts +1 -1
  54. package/app/package.json +2 -2
  55. package/bin/cli.js +27 -97
  56. package/package.json +4 -2
  57. package/scripts/setup.js +2 -12
  58. package/skills/mindos/SKILL.md +226 -8
  59. package/skills/mindos-zh/SKILL.md +226 -8
  60. package/app/package-lock.json +0 -15736
@@ -41,7 +41,7 @@ export const zh = {
41
41
  createToActivate: '创建 {file} 以启用此插件',
42
42
  shortcuts: {
43
43
  searchFiles: '搜索文件',
44
- askAI: ' AI',
44
+ askAI: 'MindOS Agent',
45
45
  editFile: '编辑文件',
46
46
  save: '保存',
47
47
  settings: '设置',
@@ -55,7 +55,7 @@ export const zh = {
55
55
  },
56
56
  sidebar: {
57
57
  searchTitle: '搜索 (⌘K)',
58
- askTitle: ' AI (⌘/)',
58
+ askTitle: 'MindOS Agent (⌘/)',
59
59
  settingsTitle: '设置 (⌘,)',
60
60
  collapseTitle: '收起侧栏',
61
61
  expandTitle: '展开侧栏',
@@ -129,7 +129,7 @@ export const zh = {
129
129
  },
130
130
  settings: {
131
131
  title: '设置',
132
- tabs: { ai: 'AI', appearance: '外观', knowledge: '知识库', sync: '同步', mcp: 'MCP', plugins: '插件', shortcuts: '快捷键' },
132
+ tabs: { ai: 'AI', appearance: '外观', knowledge: '通用', sync: '同步', mcp: 'MCP & Skills', plugins: '插件', shortcuts: '快捷键', monitoring: '监控', agents: 'Agents' },
133
133
  ai: {
134
134
  provider: '服务商',
135
135
  model: '模型',
@@ -287,6 +287,49 @@ export const zh = {
287
287
  configureFor: '配置目标',
288
288
  configPath: '配置路径',
289
289
  },
290
+ monitoring: {
291
+ system: '系统',
292
+ heapMemory: '堆内存',
293
+ rss: 'RSS',
294
+ uptime: '运行时间',
295
+ nodeVersion: 'Node',
296
+ application: '应用',
297
+ requests: '请求数',
298
+ toolCalls: '工具调用',
299
+ avgResponse: '平均响应',
300
+ tokens: 'Token',
301
+ errors: '错误',
302
+ knowledgeBase: '知识库',
303
+ files: '文件数',
304
+ totalSize: '总大小',
305
+ rootPath: '根目录',
306
+ mcpStatus: '状态',
307
+ mcpRunning: '运行中',
308
+ mcpStopped: '已停止',
309
+ mcpPort: '端口',
310
+ autoRefresh: '每 5 秒自动刷新',
311
+ fetchError: '加载监控数据失败',
312
+ },
313
+ agents: {
314
+ mcpServer: 'MCP 服务器',
315
+ running: '运行中',
316
+ stopped: '未运行',
317
+ onPort: (port: number) => `端口 :${port}`,
318
+ refresh: '刷新',
319
+ refreshing: '刷新中...',
320
+ connected: '已连接',
321
+ connectedCount: (n: number) => `已连接 (${n})`,
322
+ detectedNotConfigured: '已检测未配置',
323
+ detectedCount: (n: number) => `已检测未配置 (${n})`,
324
+ notDetected: '未检测到',
325
+ notDetectedCount: (n: number) => `未检测到 (${n})`,
326
+ showAll: '显示全部',
327
+ hideAll: '收起',
328
+ connect: '连接',
329
+ noAgents: '本机未检测到任何 Agent。',
330
+ fetchError: '加载 Agent 数据失败',
331
+ autoRefresh: '每 30 秒自动刷新',
332
+ },
290
333
  save: '保存',
291
334
  saved: '已保存',
292
335
  saveFailed: '保存失败',
@@ -305,7 +348,7 @@ export const zh = {
305
348
  },
306
349
  shortcuts: [
307
350
  { keys: ['⌘', 'K'], description: '搜索' },
308
- { keys: ['⌘', '/'], description: ' AI' },
351
+ { keys: ['⌘', '/'], description: 'MindOS Agent' },
309
352
  { keys: ['⌘', ','], description: '设置' },
310
353
  { keys: ['E'], description: '编辑当前文件' },
311
354
  { keys: ['⌘', 'S'], description: '保存' },
@@ -450,7 +493,7 @@ export const zh = {
450
493
  welcomeTitle: '欢迎使用 MindOS!',
451
494
  welcomeDesc: '初始化完成。可以开始向 AI 提问、浏览知识库,或配置 MCP Agent。',
452
495
  welcomeLinkReconfigure: '重新配置',
453
- welcomeLinkAskAI: ' AI',
496
+ welcomeLinkAskAI: 'MindOS Agent',
454
497
  welcomeLinkMCP: 'MCP 设置',
455
498
  },
456
499
  guide: {
@@ -0,0 +1,81 @@
1
+ /**
2
+ * In-memory metrics collector for MindOS runtime observability.
3
+ *
4
+ * Singleton — import { metrics } from '@/lib/metrics' in any server-side code.
5
+ * Data resets when the process restarts (no persistence needed).
6
+ */
7
+
8
+ export interface MetricsSnapshot {
9
+ processStartTime: number;
10
+ agentRequests: number;
11
+ toolExecutions: number;
12
+ totalTokens: { input: number; output: number };
13
+ avgResponseTimeMs: number;
14
+ errors: number;
15
+ }
16
+
17
+ const MAX_RESPONSE_TIMES = 100;
18
+
19
+ class MetricsCollector {
20
+ private processStartTime = Date.now();
21
+ private agentRequests = 0;
22
+ private toolExecutions = 0;
23
+ private totalTokens = { input: 0, output: 0 };
24
+ private responseTimes: number[] = [];
25
+ private errors = 0;
26
+
27
+ /** Record a completed agent request with its duration. */
28
+ recordRequest(durationMs: number): void {
29
+ this.agentRequests++;
30
+ this.responseTimes.push(durationMs);
31
+ if (this.responseTimes.length > MAX_RESPONSE_TIMES) {
32
+ this.responseTimes.shift();
33
+ }
34
+ }
35
+
36
+ /** Increment the tool execution counter. */
37
+ recordToolExecution(): void {
38
+ this.toolExecutions++;
39
+ }
40
+
41
+ /** Accumulate token usage. */
42
+ recordTokens(input: number, output: number): void {
43
+ this.totalTokens.input += input;
44
+ this.totalTokens.output += output;
45
+ }
46
+
47
+ /** Increment the error counter. */
48
+ recordError(): void {
49
+ this.errors++;
50
+ }
51
+
52
+ /** Return a read-only snapshot of all metrics. */
53
+ getSnapshot(): MetricsSnapshot {
54
+ const avg =
55
+ this.responseTimes.length > 0
56
+ ? Math.round(this.responseTimes.reduce((a, b) => a + b, 0) / this.responseTimes.length)
57
+ : 0;
58
+
59
+ return {
60
+ processStartTime: this.processStartTime,
61
+ agentRequests: this.agentRequests,
62
+ toolExecutions: this.toolExecutions,
63
+ totalTokens: { ...this.totalTokens },
64
+ avgResponseTimeMs: avg,
65
+ errors: this.errors,
66
+ };
67
+ }
68
+
69
+ /** Reset all counters (useful for testing). */
70
+ reset(): void {
71
+ this.processStartTime = Date.now();
72
+ this.agentRequests = 0;
73
+ this.toolExecutions = 0;
74
+ this.totalTokens = { input: 0, output: 0 };
75
+ this.responseTimes = [];
76
+ this.errors = 0;
77
+ }
78
+ }
79
+
80
+ /** Global singleton — shared across all requests in the same Node process. */
81
+ export const metrics = new MetricsCollector();
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.
@@ -3,7 +3,7 @@ import path from "path";
3
3
 
4
4
  const nextConfig: NextConfig = {
5
5
  transpilePackages: ['github-slugger'],
6
- serverExternalPackages: ['pdfjs-dist', 'pdf-parse', 'chokidar'],
6
+ serverExternalPackages: ['pdfjs-dist', 'pdf-parse', 'chokidar', 'openai', '@mariozechner/pi-ai', '@mariozechner/pi-agent-core'],
7
7
  outputFileTracingRoot: path.join(__dirname),
8
8
  turbopack: {
9
9
  root: path.join(__dirname),
package/app/package.json CHANGED
@@ -16,8 +16,8 @@
16
16
  "@codemirror/state": "^6.5.4",
17
17
  "@codemirror/theme-one-dark": "^6.1.3",
18
18
  "@codemirror/view": "^6.39.16",
19
- "@mariozechner/pi-agent-core": "^0.60.0",
20
- "@mariozechner/pi-ai": "^0.60.0",
19
+ "@mariozechner/pi-agent-core": "^0.61.0",
20
+ "@mariozechner/pi-ai": "^0.61.0",
21
21
  "@sinclair/typebox": "^0.34.33",
22
22
  "@tiptap/extension-image": "^3.20.1",
23
23
  "@tiptap/extension-link": "^3.20.1",
package/bin/cli.js CHANGED
@@ -245,7 +245,7 @@ const commands = {
245
245
  // Do NOT call start() here — kickstart -k would kill the just-started process,
246
246
  // causing a port-conflict race condition with KeepAlive restart loops.
247
247
  console.log(dim(' (First run may take a few minutes to install dependencies and build the app.)'));
248
- const ready = await waitForHttp(Number(webPort), { retries: 60, intervalMs: 2000, label: 'Web UI', logFile: LOG_PATH });
248
+ const ready = await waitForHttp(Number(webPort), { retries: 120, intervalMs: 2000, label: 'Web UI', logFile: LOG_PATH });
249
249
  if (!ready) {
250
250
  console.error(red('\n✘ Service started but Web UI did not become ready in time.'));
251
251
  console.error(dim(' Check logs with: mindos logs\n'));
@@ -271,36 +271,22 @@ const commands = {
271
271
  const webPort = process.env.MINDOS_WEB_PORT || '3456';
272
272
  const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
273
273
 
274
- // ── Auto-migrate skill rules (v3 split v4 merged) ──────────────────
274
+ // ── Auto-migrate user-rules.md to root user-skill-rules.md ─────────────
275
275
  try {
276
276
  const cfg = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
277
277
  const mr = cfg.mindRoot;
278
278
  if (mr && existsSync(mr)) {
279
279
  const isZh = cfg.disabledSkills?.includes('mindos');
280
280
  const sName = isZh ? 'mindos-zh' : 'mindos';
281
- const lang = isZh ? 'zh' : 'en';
282
281
  const sDir = resolve(mr, '.agents', 'skills', sName);
283
- const merged = resolve(sDir, 'skill-rules.md');
284
- const legacyRules = resolve(sDir, 'rules.md');
285
- // Migrate if legacy exists but merged doesn't
286
- if (existsSync(legacyRules) && !existsSync(merged)) {
287
- const tpl = resolve(ROOT, 'templates', 'skill-rules', lang, 'skill-rules.md');
288
- if (existsSync(tpl)) {
289
- cpSync(tpl, merged);
290
- for (const f of ['rules.md', 'patterns.md', 'proactive.md']) {
291
- const p = resolve(sDir, f);
292
- if (existsSync(p)) rmSync(p);
293
- }
294
- console.log(` ${green('✓')} ${dim('Skill rules migrated to skill-rules.md')}`);
295
- }
296
- }
297
- // Init if .agents/skills/ doesn't exist at all
298
- if (!existsSync(sDir)) {
299
- const srcDir = resolve(ROOT, 'templates', 'skill-rules', lang);
300
- if (existsSync(srcDir)) {
301
- mkdirSync(sDir, { recursive: true });
302
- cpSync(srcDir, sDir, { recursive: true });
303
- console.log(` ${green('✓')} ${dim('Skill rules initialized')}`);
282
+ const rootUserRules = resolve(mr, 'user-skill-rules.md');
283
+
284
+ // Migrate: .agents/skills/{name}/user-rules.md {mindRoot}/user-skill-rules.md
285
+ if (!existsSync(rootUserRules)) {
286
+ const oldUserRules = resolve(sDir, 'user-rules.md');
287
+ if (existsSync(oldUserRules)) {
288
+ cpSync(oldUserRules, rootUserRules);
289
+ console.log(` ${green('')} ${dim('Migrated user-rules.md → user-skill-rules.md')}`);
304
290
  }
305
291
  }
306
292
  }
@@ -440,7 +426,6 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
440
426
 
441
427
  // ── init-skills ──────────────────────────────────────────────────────────
442
428
  'init-skills': async () => {
443
- const force = process.argv.includes('--force');
444
429
  console.log(`\n${bold('📦 Initialize Skill Rules')}\n`);
445
430
 
446
431
  if (!existsSync(CONFIG_PATH)) {
@@ -460,56 +445,23 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
460
445
  process.exit(1);
461
446
  }
462
447
 
463
- const isZh = config.disabledSkills?.includes('mindos');
464
- const skillName = isZh ? 'mindos-zh' : 'mindos';
465
- const lang = isZh ? 'zh' : 'en';
466
- const skillDir = resolve(mindRoot, '.agents', 'skills', skillName);
467
- const sourceDir = resolve(ROOT, 'templates', 'skill-rules', lang);
468
-
469
- if (!existsSync(sourceDir)) {
470
- console.log(` ${red('✘')} Template not found: ${dim(sourceDir)}\n`);
471
- process.exit(1);
472
- }
473
-
474
- const files = ['skill-rules.md', 'user-rules.md'];
475
- mkdirSync(skillDir, { recursive: true });
476
-
477
- let count = 0;
478
- for (const file of files) {
479
- const dest = resolve(skillDir, file);
480
- const src = resolve(sourceDir, file);
481
- if (!existsSync(src)) continue;
482
-
483
- // Never overwrite user-rules.md even with --force
484
- if (file === 'user-rules.md' && existsSync(dest)) {
485
- console.log(` ${dim('skip')} ${file} (user rules preserved)`);
486
- continue;
487
- }
488
-
489
- if (existsSync(dest) && !force) {
490
- console.log(` ${dim('skip')} ${file} (already exists)`);
491
- continue;
492
- }
493
-
494
- cpSync(src, dest);
495
- console.log(` ${green('✓')} ${file}${force ? ' (reset)' : ''}`);
496
- count++;
497
- }
498
-
499
- // Clean up legacy split files from v3
500
- for (const legacy of ['rules.md', 'patterns.md', 'proactive.md']) {
501
- const legacyPath = resolve(skillDir, legacy);
502
- if (existsSync(legacyPath)) {
503
- rmSync(legacyPath);
504
- console.log(` ${dim('cleanup')} ${legacy} (merged into skill-rules.md)`);
505
- }
506
- }
507
-
508
- if (count === 0) {
509
- console.log(`\n ${dim('All files already exist. Use --force to reset defaults (user-rules.md is always preserved).')}\n`);
448
+ // Skill operating rules are now built into SKILL.md (shipped with the app).
449
+ // This command only initializes user-skill-rules.md for personalization.
450
+ const dest = resolve(mindRoot, 'user-skill-rules.md');
451
+ if (existsSync(dest)) {
452
+ console.log(` ${dim('skip')} user-skill-rules.md (already exists)\n`);
510
453
  } else {
511
- console.log(`\n ${green('')} Skill rules initialized at ${dim(skillDir)}\n`);
454
+ const isZh = config.disabledSkills?.includes('mindos');
455
+ const lang = isZh ? 'zh' : 'en';
456
+ const src = resolve(ROOT, 'templates', 'skill-rules', lang, 'user-rules.md');
457
+ if (existsSync(src)) {
458
+ cpSync(src, dest);
459
+ console.log(` ${green('✓')} user-skill-rules.md created at ${dim(mindRoot)}\n`);
460
+ } else {
461
+ console.log(` ${dim('skip')} Template not found, create user-skill-rules.md manually if needed.\n`);
462
+ }
512
463
  }
464
+ console.log(` ${dim('Note: Operating rules are now built into the app. No install needed.')}\n`);
513
465
  },
514
466
 
515
467
  // ── doctor ─────────────────────────────────────────────────────────────────
@@ -727,7 +679,7 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
727
679
  const webPort = updateConfig.port ?? 3456;
728
680
  const mcpPort = updateConfig.mcpPort ?? 8781;
729
681
  console.log(dim(' (Waiting for Web UI to come back up — first run after update includes a rebuild...)'));
730
- const ready = await waitForHttp(Number(webPort), { retries: 60, intervalMs: 2000, label: 'Web UI', logFile: LOG_PATH });
682
+ const ready = await waitForHttp(Number(webPort), { retries: 120, intervalMs: 2000, label: 'Web UI', logFile: LOG_PATH });
731
683
  if (ready) {
732
684
  const localIP = getLocalIP();
733
685
  console.log(`\n${'─'.repeat(53)}`);
@@ -746,28 +698,6 @@ ${dim('Shortcut: mindos start --daemon → install + start in one step')}
746
698
  console.log(dim(' Run `mindos start` — it will rebuild automatically.'));
747
699
  console.log(` ${dim('View changelog:')} ${cyan('https://github.com/GeminiLight/MindOS/releases')}\n`);
748
700
  }
749
-
750
- // ── Check if skill rules need updating ──────────────────────────────────
751
- try {
752
- const updateCfg = JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
753
- const mindRoot = updateCfg.mindRoot;
754
- if (mindRoot && existsSync(mindRoot)) {
755
- const isZh = updateCfg.disabledSkills?.includes('mindos');
756
- const sName = isZh ? 'mindos-zh' : 'mindos';
757
- const lang = isZh ? 'zh' : 'en';
758
- const installedRules = resolve(mindRoot, '.agents', 'skills', sName, 'skill-rules.md');
759
- const tplRules = resolve(ROOT, 'templates', 'skill-rules', lang, 'skill-rules.md');
760
- if (existsSync(installedRules) && existsSync(tplRules)) {
761
- const uVer = readFileSync(installedRules, 'utf-8').match(/<!--\s*version:\s*(\S+)\s*-->/)?.[1];
762
- const tVer = readFileSync(tplRules, 'utf-8').match(/<!--\s*version:\s*(\S+)\s*-->/)?.[1];
763
- if (uVer && tVer && uVer !== tVer) {
764
- console.log(` ${yellow('!')} Skill rules ${dim(uVer)} → ${bold(tVer)} available. Run ${cyan('mindos init-skills --force')} to update ${dim('(user-rules.md preserved)')}\n`);
765
- }
766
- } else if (!existsSync(resolve(mindRoot, '.agents', 'skills', sName))) {
767
- console.log(` ${dim('Tip:')} Run ${cyan('mindos init-skills')} to enable skill rules in your knowledge base.\n`);
768
- }
769
- }
770
- } catch {}
771
701
  },
772
702
 
773
703
  // ── uninstall ──────────────────────────────────────────────────────────────
@@ -1212,7 +1142,7 @@ ${row('mindos gateway <subcommand>', 'Manage background service (install/u
1212
1142
  ${bold('Config & Diagnostics:')}
1213
1143
  ${row('mindos config <subcommand>', 'View/update config (show/validate/set/unset)')}
1214
1144
  ${row('mindos doctor', 'Health check (config, ports, build, daemon)')}
1215
- ${row('mindos init-skills [--force]', 'Initialize skill rules in knowledge base')}
1145
+ ${row('mindos init-skills', 'Create user-skill-rules.md for personalization')}
1216
1146
  ${row('mindos update', 'Update MindOS to the latest version')}
1217
1147
  ${row('mindos uninstall', 'Fully uninstall MindOS (stop, remove daemon, npm uninstall)')}
1218
1148
  ${row('mindos logs', 'Tail service logs (~/.mindos/mindos.log)')}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.5.21",
3
+ "version": "0.5.23",
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",
@@ -57,7 +57,9 @@
57
57
  "!assets/images",
58
58
  "!mcp/node_modules",
59
59
  "!mcp/dist",
60
- "!mcp/package-lock.json"
60
+ "!mcp/package-lock.json",
61
+ "!mcp/*.tgz",
62
+ "!app/package-lock.json"
61
63
  ],
62
64
  "scripts": {
63
65
  "setup": "node scripts/setup.js",
package/scripts/setup.js CHANGED
@@ -1205,18 +1205,8 @@ async function main() {
1205
1205
  writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n');
1206
1206
  console.log(`\n${c.green(t('cfgSaved'))}: ${c.dim(CONFIG_PATH)}`);
1207
1207
 
1208
- // ── Init skill rules in knowledge base ────────────────────────────────────
1209
- const skillName = selectedTemplate === 'zh' ? 'mindos-zh' : 'mindos';
1210
- const skillRulesDir = resolve(mindDir, '.agents', 'skills', skillName);
1211
- if (!existsSync(skillRulesDir)) {
1212
- const skillRulesLang = selectedTemplate === 'zh' ? 'zh' : 'en';
1213
- const skillRulesSource = resolve(ROOT, 'templates', 'skill-rules', skillRulesLang);
1214
- if (existsSync(skillRulesSource)) {
1215
- mkdirSync(skillRulesDir, { recursive: true });
1216
- cpSync(skillRulesSource, skillRulesDir, { recursive: true });
1217
- console.log(`${c.green('✓')} ${c.dim(`Skill rules initialized: ${skillRulesDir}`)}`);
1218
- }
1219
- }
1208
+ // ── Skill rules are now built into SKILL.md — no install needed ──────────
1209
+ // user-skill-rules.md will be created on first preference capture or via `mindos init-skills`.
1220
1210
 
1221
1211
  // ── Step 7: MCP Agent Install ──────────────────────────────────────────────
1222
1212
  write('\n');