momo-ai 1.0.72 → 1.0.73

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/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "momo-ai",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
4
4
  "description": "Rachel Momo ( OpenSpec )",
5
5
  "main": "src/momo.js",
6
6
  "bin": {
7
- "momo": "./src/momo.js",
8
- "lain": "./src/lain.js"
7
+ "momo": "src/momo.js",
8
+ "lain": "src/lain.js"
9
9
  },
10
10
  "scripts": {
11
11
  "test": "src/index.test.js"
@@ -8,6 +8,12 @@
8
8
  "alias": "d",
9
9
  "description": "目标目录(默认当前目录)",
10
10
  "type": "string"
11
+ },
12
+ {
13
+ "name": "remove",
14
+ "alias": "r",
15
+ "description": "清理指定目录的 Obsidian 配置(与 -d 互斥)",
16
+ "type": "string"
11
17
  }
12
18
  ]
13
19
  }
@@ -7,6 +7,20 @@ const Ec = require('../epic');
7
7
  const { parseOptional } = require('../utils/momo-args');
8
8
  const { copyDir } = require('../utils/momo-file-utils');
9
9
 
10
+ const _getObsidianConfigPath = () => {
11
+ const platform = os.platform();
12
+
13
+ if (platform === 'darwin') {
14
+ return path.join(os.homedir(), 'Library/Application Support/obsidian/obsidian.json');
15
+ }
16
+ if (platform === 'win32') {
17
+ return path.join(process.env.APPDATA || '', 'obsidian', 'obsidian.json');
18
+ }
19
+
20
+ const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
21
+ return path.join(xdgConfig, 'obsidian', 'obsidian.json');
22
+ };
23
+
10
24
  /**
11
25
  * 检查 Obsidian 是否已安装
12
26
  * @returns {Promise<boolean>}
@@ -54,17 +68,7 @@ const _isObsidianInstalled = async () => {
54
68
  * @returns {Promise<boolean>}
55
69
  */
56
70
  const _isVaultRunning = async (vaultPath) => {
57
- const platform = os.platform();
58
- let configPath;
59
-
60
- if (platform === 'darwin') {
61
- configPath = path.join(os.homedir(), 'Library/Application Support/obsidian/obsidian.json');
62
- } else if (platform === 'win32') {
63
- configPath = path.join(process.env.APPDATA || '', 'obsidian', 'obsidian.json');
64
- } else {
65
- const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
66
- configPath = path.join(xdgConfig, 'obsidian', 'obsidian.json');
67
- }
71
+ const configPath = _getObsidianConfigPath();
68
72
 
69
73
  try {
70
74
  if (!fs.existsSync(configPath)) {
@@ -92,17 +96,7 @@ const _isVaultRunning = async (vaultPath) => {
92
96
  * @returns {Promise<void>}
93
97
  */
94
98
  const _closeVault = async (vaultPath) => {
95
- const platform = os.platform();
96
- let configPath;
97
-
98
- if (platform === 'darwin') {
99
- configPath = path.join(os.homedir(), 'Library/Application Support/obsidian/obsidian.json');
100
- } else if (platform === 'win32') {
101
- configPath = path.join(process.env.APPDATA || '', 'obsidian', 'obsidian.json');
102
- } else {
103
- const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
104
- configPath = path.join(xdgConfig, 'obsidian', 'obsidian.json');
105
- }
99
+ const configPath = _getObsidianConfigPath();
106
100
 
107
101
  try {
108
102
  if (!fs.existsSync(configPath)) {
@@ -150,18 +144,7 @@ const _generateVaultId = () => {
150
144
  * @returns {Promise<string|null>} 返回 vault ID,失败返回 null
151
145
  */
152
146
  const _registerVaultToObsidian = async (vaultPath) => {
153
- const platform = os.platform();
154
- let configPath;
155
-
156
- if (platform === 'darwin') {
157
- configPath = path.join(os.homedir(), 'Library/Application Support/obsidian/obsidian.json');
158
- } else if (platform === 'win32') {
159
- configPath = path.join(process.env.APPDATA || '', 'obsidian', 'obsidian.json');
160
- } else {
161
- // Linux
162
- const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
163
- configPath = path.join(xdgConfig, 'obsidian', 'obsidian.json');
164
- }
147
+ const configPath = _getObsidianConfigPath();
165
148
 
166
149
  try {
167
150
  let config = { vaults: {}, frame: 'custom' };
@@ -208,6 +191,79 @@ const _registerVaultToObsidian = async (vaultPath) => {
208
191
  }
209
192
  };
210
193
 
194
+ const _removeVaultRegistration = async (vaultPath) => {
195
+ const configPath = _getObsidianConfigPath();
196
+
197
+ try {
198
+ if (!fs.existsSync(configPath)) {
199
+ return false;
200
+ }
201
+
202
+ const content = await fsAsync.readFile(configPath, 'utf8');
203
+ const config = JSON.parse(content);
204
+ let updated = false;
205
+
206
+ for (const [id, vault] of Object.entries(config.vaults || {})) {
207
+ if (vault.path === vaultPath) {
208
+ delete config.vaults[id];
209
+ updated = true;
210
+ }
211
+ }
212
+
213
+ if (!updated) {
214
+ return false;
215
+ }
216
+
217
+ await fsAsync.writeFile(configPath, JSON.stringify(config), 'utf8');
218
+ return true;
219
+ } catch (error) {
220
+ Ec.warn(`⚠ 清理 vault 注册失败: ${error.message}`);
221
+ return false;
222
+ }
223
+ };
224
+
225
+ const _removeLocalObsidianConfig = async (targetDir) => {
226
+ const obsidianConfigPath = path.join(targetDir, '.obsidian');
227
+
228
+ try {
229
+ if (!fs.existsSync(obsidianConfigPath)) {
230
+ return false;
231
+ }
232
+
233
+ await fsAsync.rm(obsidianConfigPath, { recursive: true, force: true });
234
+ return true;
235
+ } catch (error) {
236
+ Ec.warn(`⚠ 清理本地 .obsidian 失败: ${error.message}`);
237
+ return false;
238
+ }
239
+ };
240
+
241
+ const _resetVaultConfig = async (targetDir) => {
242
+ Ec.waiting(`正在清理 Obsidian 配置: ${targetDir.cyan}...`);
243
+
244
+ const isVaultRunning = await _isVaultRunning(targetDir);
245
+ if (isVaultRunning) {
246
+ await _closeVault(targetDir);
247
+ }
248
+
249
+ const removedVault = await _removeVaultRegistration(targetDir);
250
+ const removedConfig = await _removeLocalObsidianConfig(targetDir);
251
+
252
+ if (removedVault) {
253
+ Ec.info('✓ 已移除 Obsidian 中的 vault 注册');
254
+ } else {
255
+ Ec.info('✓ 未发现需要移除的 vault 注册');
256
+ }
257
+
258
+ if (removedConfig) {
259
+ Ec.info('✓ 已删除目标目录下的 .obsidian 配置');
260
+ } else {
261
+ Ec.info('✓ 目标目录下不存在 .obsidian 配置');
262
+ }
263
+
264
+ Ec.info('✅ Obsidian 配置清理完成');
265
+ };
266
+
211
267
  /**
212
268
  * 使用 Obsidian 打开目录
213
269
  * 直接调用 Obsidian 可执行文件,传递目录路径作为参数
@@ -429,11 +485,21 @@ const _updateGitignore = async (targetDir) => {
429
485
 
430
486
  module.exports = async (options) => {
431
487
  try {
432
- // 1. 解析 -d 参数,获取目标目录
488
+ // 1. 解析 -d/-r 参数,获取目标目录
433
489
  const dirArg = parseOptional('dir', 'd');
434
- const targetDir = dirArg.hasFlag && dirArg.value
435
- ? path.resolve(dirArg.value)
436
- : process.cwd();
490
+ const removeArg = parseOptional('remove', 'r');
491
+
492
+ if (dirArg.hasFlag && removeArg.hasFlag) {
493
+ Ec.error('❌ 参数 -d/--dir 与 -r/--remove 不能同时使用');
494
+ process.exit(1);
495
+ }
496
+
497
+ let targetDir = process.cwd();
498
+ if (removeArg.hasFlag) {
499
+ targetDir = removeArg.value ? path.resolve(removeArg.value) : process.cwd();
500
+ } else if (dirArg.hasFlag) {
501
+ targetDir = dirArg.value ? path.resolve(dirArg.value) : process.cwd();
502
+ }
437
503
 
438
504
  Ec.info(`📁 目标目录: ${targetDir.cyan}`);
439
505
  Ec.info(`💻 操作系统: ${_getOsName().cyan}`);
@@ -451,6 +517,12 @@ module.exports = async (options) => {
451
517
  process.exit(1);
452
518
  }
453
519
 
520
+ if (removeArg.hasFlag) {
521
+ await _resetVaultConfig(targetDir);
522
+ console.log('');
523
+ process.exit(0);
524
+ }
525
+
454
526
  // 4. 检查 .obsidian 配置是否存在,不存在则自动初始化
455
527
  const obsidianConfigPath = path.join(targetDir, '.obsidian');
456
528
  if (!fs.existsSync(obsidianConfigPath)) {