@geminilight/mindos 0.6.22 → 0.6.25

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 (62) hide show
  1. package/README.md +58 -46
  2. package/README_zh.md +58 -46
  3. package/app/app/.well-known/agent-card.json/route.ts +34 -0
  4. package/app/app/api/a2a/route.ts +100 -0
  5. package/app/app/api/file/import/route.ts +0 -2
  6. package/app/app/api/setup/route.ts +2 -0
  7. package/app/components/Backlinks.tsx +2 -2
  8. package/app/components/Breadcrumb.tsx +1 -1
  9. package/app/components/CsvView.tsx +41 -19
  10. package/app/components/DirView.tsx +2 -2
  11. package/app/components/FileTree.tsx +14 -1
  12. package/app/components/GuideCard.tsx +6 -2
  13. package/app/components/HomeContent.tsx +2 -2
  14. package/app/components/RightAskPanel.tsx +17 -10
  15. package/app/components/SearchModal.tsx +3 -3
  16. package/app/components/SidebarLayout.tsx +4 -2
  17. package/app/components/SyncStatusBar.tsx +2 -2
  18. package/app/components/ask/AskContent.tsx +6 -6
  19. package/app/components/ask/FileChip.tsx +1 -1
  20. package/app/components/ask/MentionPopover.tsx +2 -2
  21. package/app/components/ask/MessageList.tsx +1 -1
  22. package/app/components/ask/SlashCommandPopover.tsx +1 -1
  23. package/app/components/explore/UseCaseCard.tsx +2 -2
  24. package/app/components/help/HelpContent.tsx +6 -1
  25. package/app/components/panels/AgentsPanelAgentDetail.tsx +2 -2
  26. package/app/components/panels/DiscoverPanel.tsx +3 -3
  27. package/app/components/panels/PanelNavRow.tsx +2 -2
  28. package/app/components/panels/PluginsPanel.tsx +1 -1
  29. package/app/components/panels/SearchPanel.tsx +3 -3
  30. package/app/components/renderers/summary/SummaryRenderer.tsx +1 -1
  31. package/app/components/settings/AiTab.tsx +4 -4
  32. package/app/components/settings/KnowledgeTab.tsx +1 -1
  33. package/app/components/settings/McpTab.tsx +22 -4
  34. package/app/components/settings/UpdateTab.tsx +1 -1
  35. package/app/components/setup/index.tsx +9 -3
  36. package/app/components/walkthrough/WalkthroughProvider.tsx +2 -2
  37. package/app/hooks/useAskPanel.ts +7 -3
  38. package/app/hooks/useFileImport.ts +1 -1
  39. package/app/lib/a2a/agent-card.ts +107 -0
  40. package/app/lib/a2a/index.ts +23 -0
  41. package/app/lib/a2a/task-handler.ts +228 -0
  42. package/app/lib/a2a/types.ts +158 -0
  43. package/app/lib/agent/tools.ts +1 -1
  44. package/app/lib/core/fs-ops.ts +3 -2
  45. package/app/lib/fs.ts +28 -11
  46. package/app/lib/i18n-en.ts +2 -0
  47. package/app/lib/i18n-zh.ts +2 -0
  48. package/app/lib/settings.ts +1 -1
  49. package/bin/cli.js +48 -20
  50. package/bin/commands/agent.js +18 -0
  51. package/bin/commands/api.js +58 -0
  52. package/bin/commands/ask.js +101 -0
  53. package/bin/commands/file.js +286 -0
  54. package/bin/commands/search.js +51 -0
  55. package/bin/commands/space.js +167 -0
  56. package/bin/commands/status.js +69 -0
  57. package/bin/lib/command.js +156 -0
  58. package/mcp/dist/index.cjs +1 -1
  59. package/mcp/src/index.ts +1 -1
  60. package/package.json +1 -1
  61. package/skills/mindos/SKILL.md +2 -2
  62. package/skills/mindos-zh/SKILL.md +2 -2
@@ -0,0 +1,167 @@
1
+ /**
2
+ * mindos space — Mind Space management
3
+ */
4
+
5
+ import { existsSync, readdirSync, statSync, mkdirSync, writeFileSync } from 'node:fs';
6
+ import { resolve, relative } from 'node:path';
7
+ import { bold, dim, cyan, green, red } from '../lib/colors.js';
8
+ import { loadConfig } from '../lib/config.js';
9
+ import { output, isJsonMode } from '../lib/command.js';
10
+
11
+ function getMindRoot() {
12
+ loadConfig();
13
+ const root = process.env.MIND_ROOT;
14
+ if (!root || !existsSync(root)) {
15
+ console.error(red('Mind root not configured. Run `mindos onboard` first.'));
16
+ process.exit(1);
17
+ }
18
+ return root;
19
+ }
20
+
21
+ export const meta = {
22
+ name: 'space',
23
+ group: 'Knowledge',
24
+ summary: 'Mind Space management (list, create, info)',
25
+ usage: 'mindos space <subcommand>',
26
+ examples: [
27
+ 'mindos space list',
28
+ 'mindos space list --json',
29
+ 'mindos space create "Research"',
30
+ 'mindos space info "Work"',
31
+ ],
32
+ };
33
+
34
+ export async function run(args, flags) {
35
+ const sub = args[0];
36
+ const root = getMindRoot();
37
+
38
+ if (!sub || flags.help || flags.h) {
39
+ console.log(`
40
+ ${bold('mindos space')} — Mind Space management
41
+
42
+ ${bold('Subcommands:')}
43
+ ${cyan('list'.padEnd(20))}${dim('List all spaces')}
44
+ ${cyan('create <name>'.padEnd(20))}${dim('Create a new space')}
45
+ ${cyan('info <name>'.padEnd(20))}${dim('Show space details')}
46
+
47
+ ${bold('Examples:')}
48
+ ${dim('mindos space list')}
49
+ ${dim('mindos space create "Research"')}
50
+ `);
51
+ return;
52
+ }
53
+
54
+ switch (sub) {
55
+ case 'list': return spaceList(root, flags);
56
+ case 'ls': return spaceList(root, flags);
57
+ case 'create': return spaceCreate(root, args[1], flags);
58
+ case 'info': return spaceInfo(root, args[1], flags);
59
+ default:
60
+ console.error(red(`Unknown subcommand: ${sub}`));
61
+ console.error(dim('Available: list, create, info'));
62
+ process.exit(1);
63
+ }
64
+ }
65
+
66
+ function isSpace(dir) {
67
+ // A space is a top-level directory that contains an INSTRUCTION.md
68
+ return existsSync(resolve(dir, 'INSTRUCTION.md'));
69
+ }
70
+
71
+ function countFiles(dir) {
72
+ let count = 0;
73
+ try {
74
+ const entries = readdirSync(dir, { withFileTypes: true });
75
+ for (const e of entries) {
76
+ if (e.name.startsWith('.')) continue;
77
+ if (e.isFile()) count++;
78
+ else if (e.isDirectory()) count += countFiles(resolve(dir, e.name));
79
+ }
80
+ } catch { /* skip */ }
81
+ return count;
82
+ }
83
+
84
+ function spaceList(root, flags) {
85
+ const entries = readdirSync(root, { withFileTypes: true });
86
+ const spaces = [];
87
+
88
+ for (const e of entries) {
89
+ if (!e.isDirectory() || e.name.startsWith('.')) continue;
90
+ const full = resolve(root, e.name);
91
+ if (isSpace(full)) {
92
+ const fileCount = countFiles(full);
93
+ spaces.push({ name: e.name, path: e.name, fileCount });
94
+ }
95
+ }
96
+
97
+ if (isJsonMode(flags)) {
98
+ output({ count: spaces.length, spaces }, flags);
99
+ return;
100
+ }
101
+
102
+ if (spaces.length === 0) {
103
+ console.log(dim('No spaces found. Create one with: mindos space create "Name"'));
104
+ return;
105
+ }
106
+
107
+ console.log(`\n${bold(`Spaces (${spaces.length}):`)}\n`);
108
+ for (const s of spaces) {
109
+ console.log(` ${cyan(s.name.padEnd(30))}${dim(`${s.fileCount} files`)}`);
110
+ }
111
+ console.log();
112
+ }
113
+
114
+ function spaceCreate(root, name, flags) {
115
+ if (!name) {
116
+ console.error(red('Usage: mindos space create <name>'));
117
+ process.exit(1);
118
+ }
119
+ const dir = resolve(root, name);
120
+ if (existsSync(dir)) {
121
+ console.error(red(`Space already exists: ${name}`));
122
+ process.exit(1);
123
+ }
124
+
125
+ mkdirSync(dir, { recursive: true });
126
+ writeFileSync(resolve(dir, 'INSTRUCTION.md'), `# ${name}\n\nSpace instructions go here.\n`, 'utf-8');
127
+
128
+ if (isJsonMode(flags)) {
129
+ output({ ok: true, name, path: name }, flags);
130
+ return;
131
+ }
132
+ console.log(`${green('✔')} Created space: ${cyan(name)}`);
133
+ }
134
+
135
+ function spaceInfo(root, name, flags) {
136
+ if (!name) {
137
+ console.error(red('Usage: mindos space info <name>'));
138
+ process.exit(1);
139
+ }
140
+ const dir = resolve(root, name);
141
+ if (!existsSync(dir)) {
142
+ console.error(red(`Space not found: ${name}`));
143
+ process.exit(1);
144
+ }
145
+
146
+ const fileCount = countFiles(dir);
147
+ const stat = statSync(dir);
148
+
149
+ const info = {
150
+ name,
151
+ path: name,
152
+ fileCount,
153
+ isSpace: isSpace(dir),
154
+ modified: stat.mtime.toISOString(),
155
+ };
156
+
157
+ if (isJsonMode(flags)) {
158
+ output(info, flags);
159
+ return;
160
+ }
161
+
162
+ console.log(`\n${bold(`Space: ${name}`)}\n`);
163
+ console.log(` ${dim('Files:'.padEnd(15))}${fileCount}`);
164
+ console.log(` ${dim('Is Space:'.padEnd(15))}${info.isSpace ? green('yes') : 'no (folder)'}`);
165
+ console.log(` ${dim('Modified:'.padEnd(15))}${info.modified}`);
166
+ console.log();
167
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * mindos status — Show MindOS service status overview
3
+ */
4
+
5
+ import { existsSync, readFileSync, statSync } from 'node:fs';
6
+ import { bold, dim, cyan, green, red, yellow } from '../lib/colors.js';
7
+ import { loadConfig } from '../lib/config.js';
8
+ import { CONFIG_PATH, ROOT, MINDOS_DIR, LOG_PATH } from '../lib/constants.js';
9
+ import { isPortInUse } from '../lib/port.js';
10
+ import { output, isJsonMode } from '../lib/command.js';
11
+ import { resolve } from 'node:path';
12
+
13
+ export const meta = {
14
+ name: 'status',
15
+ group: 'Core',
16
+ summary: 'Show MindOS service status overview',
17
+ usage: 'mindos status',
18
+ examples: [
19
+ 'mindos status',
20
+ 'mindos status --json',
21
+ ],
22
+ };
23
+
24
+ export async function run(_args, flags) {
25
+ loadConfig();
26
+
27
+ const webPort = process.env.MINDOS_WEB_PORT || '3456';
28
+ const mcpPort = process.env.MINDOS_MCP_PORT || '8781';
29
+ const mindRoot = process.env.MIND_ROOT || '';
30
+
31
+ const webRunning = await isPortInUse(Number(webPort));
32
+ const mcpRunning = await isPortInUse(Number(mcpPort));
33
+
34
+ const pkgVersion = (() => {
35
+ try { return JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8')).version; } catch { return '?'; }
36
+ })();
37
+
38
+ const configExists = existsSync(CONFIG_PATH);
39
+
40
+ const logSize = (() => {
41
+ try { return statSync(LOG_PATH).size; } catch { return 0; }
42
+ })();
43
+
44
+ const data = {
45
+ version: pkgVersion,
46
+ configured: configExists,
47
+ mindRoot,
48
+ web: { port: webPort, running: webRunning },
49
+ mcp: { port: mcpPort, running: mcpRunning },
50
+ logSize,
51
+ };
52
+
53
+ if (isJsonMode(flags)) {
54
+ output(data, flags);
55
+ return;
56
+ }
57
+
58
+ const indicator = (ok) => ok ? green('● running') : dim('○ stopped');
59
+
60
+ console.log(`
61
+ ${bold('MindOS Status')} ${dim(`v${pkgVersion}`)}
62
+
63
+ ${dim('Config:'.padEnd(15))}${configExists ? green('✔ configured') : red('✘ not configured')}
64
+ ${dim('Mind Root:'.padEnd(15))}${mindRoot ? cyan(mindRoot) : dim('not set')}
65
+ ${dim('Web Server:'.padEnd(15))}${indicator(webRunning)} ${dim(`(:${webPort})`)}
66
+ ${dim('MCP Server:'.padEnd(15))}${indicator(mcpRunning)} ${dim(`(:${mcpPort})`)}
67
+ ${dim('Log:'.padEnd(15))}${logSize > 0 ? dim(`${(logSize / 1024).toFixed(1)} KB`) : dim('empty')}
68
+ `);
69
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Lightweight command registry — zero dependencies.
3
+ *
4
+ * Each command exports: { meta, run }
5
+ * meta.name — primary name
6
+ * meta.aliases — optional alias names
7
+ * meta.group — help group (Core, Knowledge, MCP, Sync, Gateway, Config)
8
+ * meta.summary — one-line description
9
+ * meta.usage — usage string (optional)
10
+ * meta.flags — { flag: description } (optional)
11
+ * run(args, flags) — async handler
12
+ */
13
+
14
+ import { bold, dim, cyan, green, red } from './colors.js';
15
+ import { ROOT } from './constants.js';
16
+ import { readFileSync } from 'node:fs';
17
+ import { resolve } from 'node:path';
18
+
19
+ /** @type {Map<string, { meta: object, run: function }>} */
20
+ const registry = new Map();
21
+
22
+ /** @type {Map<string, string>} alias → primary name */
23
+ const aliases = new Map();
24
+
25
+ export function register(command) {
26
+ const { meta, run } = command;
27
+ registry.set(meta.name, { meta, run });
28
+ if (meta.aliases) {
29
+ for (const alias of meta.aliases) {
30
+ aliases.set(alias, meta.name);
31
+ }
32
+ }
33
+ }
34
+
35
+ export function resolve_command(name) {
36
+ if (registry.has(name)) return registry.get(name);
37
+ const primary = aliases.get(name);
38
+ if (primary) return registry.get(primary);
39
+ return null;
40
+ }
41
+
42
+ export function getAllCommands() {
43
+ return [...registry.values()];
44
+ }
45
+
46
+ /** Parse process.argv into { command, args, flags } */
47
+ export function parseArgs(argv = process.argv.slice(2)) {
48
+ const flags = {};
49
+ const args = [];
50
+ let i = 0;
51
+
52
+ while (i < argv.length) {
53
+ const arg = argv[i];
54
+ if (arg.startsWith('--')) {
55
+ const key = arg.slice(2);
56
+ // Check if next arg is a value (not a flag)
57
+ if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) {
58
+ flags[key] = argv[i + 1];
59
+ i += 2;
60
+ } else {
61
+ flags[key] = true;
62
+ i++;
63
+ }
64
+ } else if (arg.startsWith('-') && arg.length === 2) {
65
+ flags[arg.slice(1)] = true;
66
+ i++;
67
+ } else {
68
+ args.push(arg);
69
+ i++;
70
+ }
71
+ }
72
+
73
+ return { command: args[0] || null, args: args.slice(1), flags };
74
+ }
75
+
76
+ /** Check if --json flag is set */
77
+ export function isJsonMode(flags) {
78
+ return flags.json === true;
79
+ }
80
+
81
+ /** Output helper: human-readable or JSON */
82
+ export function output(data, flags) {
83
+ if (isJsonMode(flags)) {
84
+ console.log(JSON.stringify(data, null, 2));
85
+ } else if (typeof data === 'string') {
86
+ console.log(data);
87
+ } else {
88
+ console.log(JSON.stringify(data, null, 2));
89
+ }
90
+ }
91
+
92
+ /** Print global help */
93
+ export function printHelp() {
94
+ const pkgVersion = (() => {
95
+ try {
96
+ return JSON.parse(readFileSync(resolve(ROOT, 'package.json'), 'utf-8')).version;
97
+ } catch { return '?'; }
98
+ })();
99
+
100
+ const row = (c, d) => ` ${cyan(c.padEnd(38))}${dim(d)}`;
101
+
102
+ const groups = {};
103
+ for (const { meta } of registry.values()) {
104
+ const group = meta.group || 'Other';
105
+ if (!groups[group]) groups[group] = [];
106
+ const usage = meta.usage || `mindos ${meta.name}`;
107
+ groups[group].push(row(usage, meta.summary));
108
+ }
109
+
110
+ const sections = [];
111
+ const groupOrder = ['Core', 'Knowledge', 'MCP', 'Sync', 'Gateway', 'Config'];
112
+ for (const g of groupOrder) {
113
+ if (groups[g]) {
114
+ sections.push(`${bold(`${g}:`)}\n${groups[g].join('\n')}`);
115
+ }
116
+ }
117
+ // Any remaining groups
118
+ for (const [g, items] of Object.entries(groups)) {
119
+ if (!groupOrder.includes(g)) {
120
+ sections.push(`${bold(`${g}:`)}\n${items.join('\n')}`);
121
+ }
122
+ }
123
+
124
+ console.log(`
125
+ ${bold('MindOS CLI')} ${dim(`v${pkgVersion}`)}
126
+
127
+ ${sections.join('\n\n')}
128
+
129
+ ${bold('Global Flags:')}
130
+ ${cyan('--json'.padEnd(38))}${dim('Output in JSON format (for agents)')}
131
+ ${cyan('--help, -h'.padEnd(38))}${dim('Show help')}
132
+ ${cyan('--version, -v'.padEnd(38))}${dim('Show version')}
133
+ `);
134
+ }
135
+
136
+ /** Print command-specific help */
137
+ export function printCommandHelp(cmd) {
138
+ const { meta } = cmd;
139
+ const usage = meta.usage || `mindos ${meta.name}`;
140
+ console.log(`\n${bold(usage)}\n`);
141
+ console.log(` ${meta.summary}\n`);
142
+ if (meta.flags) {
143
+ console.log(`${bold('Flags:')}`);
144
+ for (const [flag, desc] of Object.entries(meta.flags)) {
145
+ console.log(` ${cyan(flag.padEnd(30))}${dim(desc)}`);
146
+ }
147
+ console.log();
148
+ }
149
+ if (meta.examples) {
150
+ console.log(`${bold('Examples:')}`);
151
+ for (const ex of meta.examples) {
152
+ console.log(` ${dim(ex)}`);
153
+ }
154
+ console.log();
155
+ }
156
+ }
@@ -107,7 +107,7 @@ data:
107
107
 
108
108
  `:r>0?`[Showing characters ${r}\u2013${r+o.length} of ${i.length}]
109
109
 
110
- `:"";return fe("mindos_read_file",{path:e},"ok",`${i.length} chars`),de(c+o)}catch(a){return fe("mindos_read_file",{path:e},"error",String(a)),be(String(a))}}),t.registerTool("mindos_write_file",{title:"Write File Content",description:"Overwrite the entire content of an existing file.",inputSchema:E.object({path:E.string().min(1),content:E.string()})},async({path:e,content:r})=>{try{return await dt("/api/file",{op:"save_file",path:e,content:r}),fe("mindos_write_file",{path:e},"ok",`Wrote ${r.length} chars`),de(`Successfully wrote ${r.length} characters to "${e}"`)}catch(n){return fe("mindos_write_file",{path:e},"error",String(n)),be(String(n))}}),t.registerTool("mindos_create_file",{title:"Create New File",description:"Create a new file in the knowledge base. Only .md and .csv files allowed.",inputSchema:E.object({path:E.string().min(1).regex(/\.(md|csv)$/),content:E.string().default("")})},async({path:e,content:r})=>{try{return await dt("/api/file",{op:"create_file",path:e,content:r}),fe("mindos_create_file",{path:e},"ok",`Created ${r.length} chars`),de(`Created "${e}" (${r.length} characters)`)}catch(n){return fe("mindos_create_file",{path:e},"error",String(n)),be(String(n))}}),t.registerTool("mindos_batch_create_files",{title:"Batch Create Files",description:"Create multiple new files in a single operation. Only .md and .csv files allowed. Returns a summary of created files and any errors.",inputSchema:E.object({files:E.array(E.object({path:E.string().min(1).regex(/\.(md|csv)$/).describe("Relative file path (must end in .md or .csv)"),content:E.string().default("").describe("Initial file content")})).min(1).max(50).describe("List of files to create (max 50 per call)")})},async({files:e})=>{let r=[],n=[];for(let i of e)try{await dt("/api/file",{op:"create_file",path:i.path,content:i.content}),r.push(i.path)}catch(o){n.push(`${i.path}: ${String(o)}`)}let a=`Batch creation complete.
110
+ `:"";return fe("mindos_read_file",{path:e},"ok",`${i.length} chars`),de(c+o)}catch(a){return fe("mindos_read_file",{path:e},"error",String(a)),be(String(a))}}),t.registerTool("mindos_write_file",{title:"Write File Content",description:"Overwrite the entire content of an existing file.",inputSchema:E.object({path:E.string().min(1),content:E.string()})},async({path:e,content:r})=>{try{return await dt("/api/file",{op:"save_file",path:e,content:r}),fe("mindos_write_file",{path:e},"ok",`Wrote ${r.length} chars`),de(`Successfully wrote ${r.length} characters to "${e}"`)}catch(n){return fe("mindos_write_file",{path:e},"error",String(n)),be(String(n))}}),t.registerTool("mindos_create_file",{title:"Create New File",description:"Create a new file in the knowledge base. Only .md and .csv files allowed. Creates parent directories but does NOT create Space scaffolding. Use mindos_create_space to create a Space.",inputSchema:E.object({path:E.string().min(1).regex(/\.(md|csv)$/),content:E.string().default("")})},async({path:e,content:r})=>{try{return await dt("/api/file",{op:"create_file",path:e,content:r}),fe("mindos_create_file",{path:e},"ok",`Created ${r.length} chars`),de(`Created "${e}" (${r.length} characters)`)}catch(n){return fe("mindos_create_file",{path:e},"error",String(n)),be(String(n))}}),t.registerTool("mindos_batch_create_files",{title:"Batch Create Files",description:"Create multiple new files in a single operation. Only .md and .csv files allowed. Returns a summary of created files and any errors.",inputSchema:E.object({files:E.array(E.object({path:E.string().min(1).regex(/\.(md|csv)$/).describe("Relative file path (must end in .md or .csv)"),content:E.string().default("").describe("Initial file content")})).min(1).max(50).describe("List of files to create (max 50 per call)")})},async({files:e})=>{let r=[],n=[];for(let i of e)try{await dt("/api/file",{op:"create_file",path:i.path,content:i.content}),r.push(i.path)}catch(o){n.push(`${i.path}: ${String(o)}`)}let a=`Batch creation complete.
111
111
  Created ${r.length} file(s): ${r.join(", ")}`;return n.length>0&&(a+=`
112
112
 
113
113
  Failed to create ${n.length} file(s):
package/mcp/src/index.ts CHANGED
@@ -190,7 +190,7 @@ server.registerTool("mindos_write_file", {
190
190
 
191
191
  server.registerTool("mindos_create_file", {
192
192
  title: "Create New File",
193
- description: "Create a new file in the knowledge base. Only .md and .csv files allowed.",
193
+ description: "Create a new file in the knowledge base. Only .md and .csv files allowed. Creates parent directories but does NOT create Space scaffolding. Use mindos_create_space to create a Space.",
194
194
  inputSchema: z.object({
195
195
  path: z.string().min(1).regex(/\.(md|csv)$/),
196
196
  content: z.string().default(""),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminilight/mindos",
3
- "version": "0.6.22",
3
+ "version": "0.6.25",
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",
@@ -105,8 +105,8 @@ Before any non-trivial write, confirm all checks:
105
105
 
106
106
  - `mindos_read_file`: Read file content.
107
107
  - `mindos_write_file`: Use only for true full replacement.
108
- - `mindos_create_file`: Create `.md`/`.csv` files.
109
- - `mindos_create_space`: Create a Mind Space (directory + README + INSTRUCTION scaffold). Prefer over `create_file` when adding a new cognitive zone.
108
+ - `mindos_create_file`: Create `.md`/`.csv` files. Creates parent directories automatically but does NOT create Space scaffolding (INSTRUCTION.md/README.md). Use `mindos_create_space` when you need a Space.
109
+ - `mindos_create_space`: Create a Mind Space (directory + README + INSTRUCTION scaffold). **This is the only way to create a Space.** Regular folders created by `create_file` remain plain directories. Use this when adding a new cognitive zone.
110
110
  - `mindos_rename_space`: Rename a Space folder (directory). Do not use `rename_file` for folders.
111
111
  - `mindos_delete_file`: Delete only with explicit user intent.
112
112
  - `mindos_rename_file`, `mindos_move_file`: Structural edits with follow-up reference checks.
@@ -103,8 +103,8 @@ description: >
103
103
 
104
104
  - `mindos_read_file`:读取文件内容。
105
105
  - `mindos_write_file`:仅在确需整文件替换时使用。
106
- - `mindos_create_file`:创建 `.md`/`.csv` 文件。
107
- - `mindos_create_space`:新建心智空间(目录 + README + INSTRUCTION 脚手架)。新增整块分区时优先于只建 `某空间/README.md`。
106
+ - `mindos_create_file`:创建 `.md`/`.csv` 文件。自动创建父目录,但不会创建空间脚手架文件(INSTRUCTION.md/README.md)。需要创建空间请用 `mindos_create_space`。
107
+ - `mindos_create_space`:新建心智空间(目录 + README + INSTRUCTION 脚手架)。**这是创建空间的唯一方式。** 通过 `create_file` 创建的普通目录不会变成空间。新增整块知识分区时使用此工具。
108
108
  - `mindos_rename_space`:重命名空间目录(文件夹)。不能用 `rename_file` 重命名目录。
109
109
  - `mindos_delete_file`:仅在用户明确意图下删除。
110
110
  - `mindos_rename_file`、`mindos_move_file`:结构变更后补做引用检查。