momo-ai 1.0.20 → 1.0.22

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 (162) hide show
  1. package/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
  2. package/.claude/skills/algorithmic-art/SKILL.md +405 -0
  3. package/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
  4. package/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
  5. package/.claude/skills/r2mo-rad-lain/SKILL.md +101 -0
  6. package/.cursor/mcp.json +17 -0
  7. package/.obsidian/app.json +1 -0
  8. package/.obsidian/appearance.json +4 -0
  9. package/.obsidian/community-plugins.json +4 -0
  10. package/.obsidian/core-plugins.json +33 -0
  11. package/.obsidian/plugins/ai-agent/main.js +98495 -0
  12. package/.obsidian/plugins/ai-agent/manifest.json +11 -0
  13. package/.obsidian/plugins/ai-agent/styles.css +806 -0
  14. package/.obsidian/plugins/dataview/main.js +20876 -0
  15. package/.obsidian/plugins/dataview/manifest.json +11 -0
  16. package/.obsidian/plugins/dataview/styles.css +141 -0
  17. package/.obsidian/plugins/obsidian-excalidraw-plugin/main.js +10 -0
  18. package/.obsidian/plugins/obsidian-excalidraw-plugin/manifest.json +12 -0
  19. package/.obsidian/plugins/obsidian-excalidraw-plugin/styles.css +1 -0
  20. package/.obsidian/plugins/templater-obsidian/main.js +45 -0
  21. package/.obsidian/plugins/templater-obsidian/manifest.json +11 -0
  22. package/.obsidian/plugins/templater-obsidian/styles.css +226 -0
  23. package/.obsidian/plugins/terminal/main.js +200 -0
  24. package/.obsidian/plugins/terminal/manifest.json +14 -0
  25. package/.obsidian/plugins/terminal/styles.css +32 -0
  26. package/.obsidian/themes/AnuPpuccin/manifest.json +7 -0
  27. package/.obsidian/themes/AnuPpuccin/theme.css +9080 -0
  28. package/.obsidian/themes/Things/manifest.json +7 -0
  29. package/.obsidian/themes/Things/theme.css +1628 -0
  30. package/.obsidian/workspace.json +196 -0
  31. package/.trae/skills/algorithmic-art/LICENSE.txt +202 -0
  32. package/.trae/skills/algorithmic-art/SKILL.md +405 -0
  33. package/.trae/skills/algorithmic-art/templates/generator_template.js +223 -0
  34. package/.trae/skills/algorithmic-art/templates/viewer.html +599 -0
  35. package/.trae/skills/doc-coauthoring/SKILL.md +375 -0
  36. package/.trae/skills/frontend-design/LICENSE.txt +177 -0
  37. package/.trae/skills/frontend-design/SKILL.md +42 -0
  38. package/.trae/skills/r2mo-rad-lain/SKILL.md +101 -0
  39. package/README.md +12 -148
  40. package/docs/images/logo.jpeg +0 -0
  41. package/docs/images/r2mo-lain.png +0 -0
  42. package/install.sh +1 -0
  43. package/package.json +15 -11
  44. package/skills/r2mo-rad-domain/SKILL.md +70 -0
  45. package/skills/r2mo-rad-lain/SKILL.md +101 -0
  46. package/src/_mcp/skills-server.mjs +70 -0
  47. package/src/_skill/repositories.json +22 -0
  48. package/src/_template/LAIN/.obsidian/app.json +1 -0
  49. package/src/_template/LAIN/.obsidian/appearance.json +10 -0
  50. package/src/_template/LAIN/.obsidian/community-plugins.json +7 -0
  51. package/src/_template/LAIN/.obsidian/core-plugins.json +33 -0
  52. package/src/_template/LAIN/.obsidian/plugins/dataview/main.js +20876 -0
  53. package/src/_template/LAIN/.obsidian/plugins/dataview/manifest.json +11 -0
  54. package/src/_template/LAIN/.obsidian/plugins/dataview/styles.css +141 -0
  55. package/src/_template/LAIN/.obsidian/plugins/obsidian-excalidraw-plugin/data.json +815 -0
  56. package/src/_template/LAIN/.obsidian/plugins/obsidian-excalidraw-plugin/main.js +10 -0
  57. package/src/_template/LAIN/.obsidian/plugins/obsidian-excalidraw-plugin/manifest.json +12 -0
  58. package/src/_template/LAIN/.obsidian/plugins/obsidian-excalidraw-plugin/styles.css +1 -0
  59. package/src/_template/LAIN/.obsidian/plugins/obsidian-kanban/main.js +153 -0
  60. package/src/_template/LAIN/.obsidian/plugins/obsidian-kanban/manifest.json +11 -0
  61. package/src/_template/LAIN/.obsidian/plugins/obsidian-kanban/styles.css +1 -0
  62. package/src/_template/LAIN/.obsidian/plugins/obsidian-plantuml/main.js +7732 -0
  63. package/src/_template/LAIN/.obsidian/plugins/obsidian-plantuml/manifest.json +10 -0
  64. package/src/_template/LAIN/.obsidian/plugins/obsidian-plantuml/styles.css +38 -0
  65. package/src/_template/LAIN/.obsidian/plugins/obsidian-tasks-plugin/main.js +504 -0
  66. package/src/_template/LAIN/.obsidian/plugins/obsidian-tasks-plugin/manifest.json +12 -0
  67. package/src/_template/LAIN/.obsidian/plugins/obsidian-tasks-plugin/styles.css +1 -0
  68. package/src/_template/LAIN/.obsidian/snippets/body-font.css +27 -0
  69. package/src/_template/LAIN/.obsidian/themes/Primary/manifest.json +9 -0
  70. package/src/_template/LAIN/.obsidian/themes/Primary/theme.css +3878 -0
  71. package/src/_template/LAIN/.obsidian/themes/Retro Windows/manifest.json +7 -0
  72. package/src/_template/LAIN/.obsidian/themes/Retro Windows/theme.css +582 -0
  73. package/src/_template/LAIN/.obsidian/themes/RetroOS 98/manifest.json +9 -0
  74. package/src/_template/LAIN/.obsidian/themes/RetroOS 98/theme.css +2566 -0
  75. package/src/_template/LAIN/.obsidian/types.json +28 -0
  76. package/src/_template/LAIN/.obsidian/workspace.json +184 -0
  77. package/src/_template/LAIN/AGENTS.md +170 -16
  78. package/src/_template/R2MO/domain-enhance.md +10 -0
  79. package/src/commander/app.json +13 -0
  80. package/src/commander/apply.json +13 -0
  81. package/src/commander/ask.json +6 -0
  82. package/src/commander/docs.json +13 -0
  83. package/src/commander/domain.json +19 -0
  84. package/src/commander/help.json +5 -0
  85. package/src/commander/init.json +1 -1
  86. package/src/commander/mcp.json +13 -0
  87. package/src/commander/mmr0.json +6 -0
  88. package/src/commander/mmr2.json +6 -0
  89. package/src/commander/open.json +8 -2
  90. package/src/executor/executeApp.js +133 -0
  91. package/src/executor/executeApply.js +611 -0
  92. package/src/executor/executeAsk.js +274 -0
  93. package/src/executor/executeDocs.js +498 -0
  94. package/src/executor/executeDomain.js +293 -0
  95. package/src/executor/executeEnv.js +48 -38
  96. package/src/executor/executeHelp.js +77 -16
  97. package/src/executor/executeInit.js +176 -346
  98. package/src/executor/executeMcp.js +363 -0
  99. package/src/executor/executeMmr0.js +488 -0
  100. package/src/executor/executeMmr2.js +880 -0
  101. package/src/executor/executeOpen.js +144 -125
  102. package/src/executor/index.js +17 -39
  103. package/src/momo.js +2 -1
  104. package/src/python/r2mo_proto.py +418 -0
  105. package/src/python/r2mo_proto_database.py +369 -0
  106. package/src/python/r2mo_proto_domain.py +458 -0
  107. package/src/utils/momo-args.js +39 -0
  108. package/src/utils/momo-file-utils.js +75 -0
  109. package/src/utils/momo-menu.js +84 -0
  110. package/src/_template/LAIN/.momo/advanced/actor.md +0 -42
  111. package/src/_template/LAIN/.momo/advanced/refer.json +0 -46
  112. package/src/_template/LAIN/.momo/scripts/submodule-clean.sh +0 -56
  113. package/src/_template/LAIN/changes/proposal.md +0 -39
  114. package/src/_template/LAIN/changes/tasks/task-detail.md +0 -45
  115. package/src/_template/LAIN/changes/tasks.md +0 -49
  116. package/src/_template/LAIN/execute/admin-n-f-dashboard.md +0 -53
  117. package/src/_template/LAIN/execute/admin-n-f-form.md +0 -51
  118. package/src/_template/LAIN/execute/admin-n-f-home.md +0 -49
  119. package/src/_template/LAIN/execute/admin-n-f-list.md +0 -52
  120. package/src/_template/LAIN/execute/admin-n-f-login.md +0 -56
  121. package/src/_template/LAIN/specification/project-model.md +0 -13
  122. package/src/_template/LAIN/specification/project.md +0 -73
  123. package/src/_template/LAIN/specification/requirement.md +0 -25
  124. package/src/commander/actor.json +0 -12
  125. package/src/commander/actors.json +0 -6
  126. package/src/commander/add.json +0 -12
  127. package/src/commander/agent.json +0 -12
  128. package/src/commander/agentcfg.json +0 -5
  129. package/src/commander/archive.json +0 -12
  130. package/src/commander/commit.json +0 -12
  131. package/src/commander/console.json +0 -7
  132. package/src/commander/lain.json +0 -7
  133. package/src/commander/list.json +0 -7
  134. package/src/commander/plan.json +0 -12
  135. package/src/commander/project.json +0 -12
  136. package/src/commander/pull.json +0 -6
  137. package/src/commander/push.json +0 -6
  138. package/src/commander/repo.json +0 -18
  139. package/src/commander/run.json +0 -18
  140. package/src/commander/show.json +0 -12
  141. package/src/commander/tasks.json +0 -18
  142. package/src/commander/unlock.json +0 -6
  143. package/src/commander/validate.json +0 -12
  144. package/src/executor/executeActor.js +0 -133
  145. package/src/executor/executeActors.js +0 -58
  146. package/src/executor/executeAdd.js +0 -307
  147. package/src/executor/executeAgent.js +0 -299
  148. package/src/executor/executeAgentCfg.js +0 -210
  149. package/src/executor/executeArchive.js +0 -124
  150. package/src/executor/executeCommit.js +0 -202
  151. package/src/executor/executeConsole.js +0 -142
  152. package/src/executor/executeList.js +0 -133
  153. package/src/executor/executePlan.js +0 -164
  154. package/src/executor/executeProject.js +0 -313
  155. package/src/executor/executePull.js +0 -127
  156. package/src/executor/executePush.js +0 -243
  157. package/src/executor/executeRepo.js +0 -238
  158. package/src/executor/executeRun.js +0 -644
  159. package/src/executor/executeShow.js +0 -164
  160. package/src/executor/executeTasks.js +0 -384
  161. package/src/executor/executeUnlock.js +0 -110
  162. package/src/executor/executeValidate.js +0 -210
@@ -1,210 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { spawn } = require('child_process');
4
- const Ec = require('../epic');
5
-
6
- /**
7
- * 获取所有 agents 信息
8
- * @returns {Array} agents 信息数组
9
- */
10
- const _getAgents = () => {
11
- const agentsDir = path.resolve(__dirname, '../_agent');
12
- const agents = [];
13
-
14
- if (!fs.existsSync(agentsDir)) {
15
- return agents;
16
- }
17
-
18
- // 遍历 _agent 目录下的所有子目录
19
- const types = fs.readdirSync(agentsDir).filter(file =>
20
- fs.statSync(path.join(agentsDir, file)).isDirectory()
21
- );
22
-
23
- // 遍历每个类型目录
24
- types.forEach(type => {
25
- const typeDir = path.join(agentsDir, type);
26
- const files = fs.readdirSync(typeDir).filter(file => file.endsWith('.json'));
27
-
28
- // 遍历每个 json 文件
29
- files.forEach(file => {
30
- try {
31
- const filePath = path.join(typeDir, file);
32
- const content = fs.readFileSync(filePath, 'utf8');
33
- const agentInfo = JSON.parse(content);
34
-
35
- agents.push({
36
- argName: file.replace('momo-', '').replace('.json', ''),
37
- type: type,
38
- name: agentInfo.name,
39
- id: agentInfo.id,
40
- uri: agentInfo.uri,
41
- uriCn: agentInfo['uri-cn'], // 添加CN链接
42
- filePath: filePath
43
- });
44
- } catch (error) {
45
- Ec.waiting(`⚠️ 无法解析文件: ${file} - ${error.message}`);
46
- }
47
- });
48
- });
49
-
50
- return agents;
51
- };
52
-
53
- /**
54
- * 显示 agents 表格
55
- * @param {Array} agents agents 信息数组
56
- */
57
- const _showAgents = (agents) => {
58
- if (agents.length === 0) {
59
- Ec.waiting('未找到任何 agents');
60
- return;
61
- }
62
-
63
- // 计算列宽
64
- const typeColumnWidth = 12;
65
- const idColumnWidth = 20;
66
- const uriColumnWidth = 35;
67
- const uriCnColumnWidth = 35;
68
- const nameColumnWidth = 35;
69
-
70
- // 表头
71
- const header = "编号".padEnd(6) +
72
- "Type".padEnd(typeColumnWidth) +
73
- "ID".padEnd(idColumnWidth) +
74
- "URI".padEnd(uriColumnWidth) +
75
- "URI-CN".padEnd(uriCnColumnWidth) +
76
- "Name".padEnd(nameColumnWidth);
77
- Ec.waiting(header);
78
-
79
- // 分隔线
80
- const separator = "-".repeat(5) + " " +
81
- "-".repeat(typeColumnWidth - 1) + " " +
82
- "-".repeat(idColumnWidth - 1) + " " +
83
- "-".repeat(uriColumnWidth - 1) + " " +
84
- "-".repeat(uriCnColumnWidth - 1) + " " +
85
- "-".repeat(nameColumnWidth - 1);
86
- Ec.waiting(separator);
87
-
88
- // 数据行
89
- agents.forEach((agent, index) => {
90
- const name = `${agent.argName} (${agent.name})`;
91
- const row = `${(index + 1).toString().padEnd(6)}` +
92
- `${agent.type.padEnd(typeColumnWidth)}` +
93
- `${agent.id.padEnd(idColumnWidth).red.bold}` +
94
- `${(agent.uri || '').padEnd(uriColumnWidth)}` +
95
- `${(agent.uriCn || '').padEnd(uriCnColumnWidth)}` +
96
- name.padEnd(nameColumnWidth);
97
- Ec.waiting(row);
98
- });
99
-
100
- Ec.waiting(separator);
101
- Ec.waiting(`${(agents.length + 1).toString().padEnd(6)}退出`);
102
- Ec.waiting('');
103
- };
104
-
105
- /**
106
- * 在浏览器中打开 URI
107
- * @param {string} uri 要打开的 URI
108
- * @param {string} agentType agent 类型
109
- */
110
- const _openInBrowser = (uri, agentType) => {
111
- Ec.waiting(`🚀 正在打开 ${agentType} 中的 agent...`);
112
-
113
- let command;
114
- switch (process.platform) {
115
- case 'darwin': // macOS
116
- command = `open "${uri}"`;
117
- break;
118
- case 'win32': // Windows
119
- command = `start "" "${uri}"`;
120
- break;
121
- default: // Linux
122
- command = `xdg-open "${uri}"`;
123
- break;
124
- }
125
-
126
- const child = spawn(command, { shell: true });
127
-
128
- child.on('error', (error) => {
129
- Ec.waiting(`⚠️ 无法打开浏览器: ${error.message}`);
130
- });
131
-
132
- child.on('close', (code) => {
133
- if (code === 0) {
134
- Ec.waiting(`✅ 浏览器已打开,请确保您的 IDE 已启动`);
135
- } else {
136
- Ec.waiting(`⚠️ 浏览器打开失败,退出码: ${code}`);
137
- }
138
- });
139
- };
140
-
141
- /**
142
- * 交互式选择 agents
143
- * @param {Array} agents agents 信息数组
144
- */
145
- const _interactiveSelect = async (agents) => {
146
- while (true) {
147
- _showAgents(agents);
148
- Ec.waiting('💡 提示: 请确保您的 IDE 已启动,以便正确配置 agent');
149
- const answer = await Ec.ask('请输入编号选择 agent (或输入退出编号): ');
150
-
151
- const selectedIndex = parseInt(answer) - 1;
152
-
153
- // 检查是否选择退出
154
- if (selectedIndex === agents.length) {
155
- Ec.waiting('👋 再见!');
156
- break;
157
- }
158
-
159
- // 检查选择是否有效
160
- if (isNaN(selectedIndex) || selectedIndex < 0 || selectedIndex >= agents.length) {
161
- Ec.waiting('❌ 无效的选择,请重新输入');
162
- continue;
163
- }
164
-
165
- // 让用户选择打开国际版还是中文版链接
166
- const selectedAgent = agents[selectedIndex];
167
- let uriToOpen = selectedAgent.uri;
168
-
169
- if (selectedAgent.uriCn) {
170
- const choice = await Ec.ask('选择打开链接版本: 1. 国际版 2. 中文版 (默认国际版): ');
171
- if (choice === '2') {
172
- uriToOpen = selectedAgent.uriCn;
173
- }
174
- }
175
-
176
- // 打开选中的 agent
177
- _openInBrowser(uriToOpen, selectedAgent.type);
178
-
179
- // 等待一段时间让用户看到结果
180
- await new Promise(resolve => setTimeout(resolve, 2000));
181
- }
182
- };
183
-
184
- module.exports = async () => {
185
- try {
186
- Ec.waiting('🔍 正在枚举所有可用的 agents...');
187
-
188
- // 获取所有 agents
189
- const agents = _getAgents();
190
-
191
- if (agents.length === 0) {
192
- Ec.waiting('❌ 未找到任何 agents');
193
- Ec.askClose();
194
- process.exit(0);
195
- }
196
-
197
- Ec.waiting(`✅ 找到 ${agents.length} 个 agents`);
198
- Ec.waiting('');
199
-
200
- // 进入交互式选择
201
- await _interactiveSelect(agents);
202
-
203
- Ec.askClose();
204
- process.exit(0);
205
- } catch (error) {
206
- Ec.error(`执行过程中发生错误: ${error.message}`);
207
- Ec.askClose();
208
- process.exit(1);
209
- }
210
- };
@@ -1,124 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const util = require('util');
4
- const Ec = require('../epic');
5
- const fsAsync = require('fs').promises;
6
-
7
- /**
8
- * 检查需求目录是否存在
9
- * @param {string} changesDir changes目录路径
10
- * @param {string} requirementName 需求名称
11
- * @returns {boolean} 是否存在
12
- */
13
- const _isRequirementExists = (changesDir, requirementName) => {
14
- const requirementDir = path.join(changesDir, requirementName);
15
- return fs.existsSync(requirementDir);
16
- };
17
-
18
- /**
19
- * 递归拷贝目录
20
- * @param {string} src 源目录
21
- * @param {string} dest 目标目录
22
- */
23
- const _copyDir = async (src, dest) => {
24
- const entries = await fsAsync.readdir(src, { withFileTypes: true });
25
- await fsAsync.mkdir(dest, { recursive: true });
26
-
27
- for (let entry of entries) {
28
- const srcPath = path.join(src, entry.name);
29
- const destPath = path.join(dest, entry.name);
30
-
31
- if (entry.isDirectory()) {
32
- await _copyDir(srcPath, destPath);
33
- } else {
34
- await fsAsync.copyFile(srcPath, destPath);
35
- }
36
- }
37
- };
38
-
39
- /**
40
- * 递归删除目录
41
- * @param {string} dirPath 目录路径
42
- */
43
- const _removeDir = async (dirPath) => {
44
- const entries = await fsAsync.readdir(dirPath, { withFileTypes: true });
45
-
46
- for (let entry of entries) {
47
- const entryPath = path.join(dirPath, entry.name);
48
-
49
- if (entry.isDirectory()) {
50
- await _removeDir(entryPath);
51
- } else {
52
- await fsAsync.unlink(entryPath);
53
- }
54
- }
55
-
56
- await fsAsync.rmdir(dirPath);
57
- };
58
-
59
- module.exports = async (options) => {
60
- // 参数提取
61
- const parsed = Ec.parseArgument(options);
62
-
63
- // 获取需求名称
64
- const requirementName = parsed.name || parsed.n;
65
-
66
- // 验证参数
67
- if (!requirementName) {
68
- Ec.error("❌ 请提供需求名称 (-n, --name)");
69
- process.exit(1);
70
- }
71
-
72
- // 检查需求名称是否包含点号(扩展名)
73
- if (requirementName.includes('.')) {
74
- Ec.error("❌ 需求名称不能包含点号(.),以防止与文件扩展名混淆");
75
- process.exit(1);
76
- }
77
-
78
- Ec.waiting(`准备归档需求: ${requirementName}`);
79
-
80
- try {
81
- // 获取项目路径
82
- const projectDir = process.cwd();
83
- const changesDir = path.join(projectDir, 'specification', 'changes');
84
- const archivesDir = path.join(projectDir, 'specification', '.archives');
85
-
86
- // 检查需求是否存在
87
- if (!_isRequirementExists(changesDir, requirementName)) {
88
- Ec.error(`❌ 需求 "${requirementName}" 不存在`);
89
- process.exit(1);
90
- }
91
-
92
- // 生成带时间戳的归档目录名 (YYYYMMDDHHMMSS-需求名)
93
- const now = new Date();
94
- const timestamp = now.getFullYear() +
95
- String(now.getMonth() + 1).padStart(2, '0') +
96
- String(now.getDate()).padStart(2, '0') +
97
- String(now.getHours()).padStart(2, '0') +
98
- String(now.getMinutes()).padStart(2, '0') +
99
- String(now.getSeconds()).padStart(2, '0');
100
-
101
- const archiveName = `${timestamp}-${requirementName}`;
102
- const archiveDir = path.join(archivesDir, archiveName);
103
-
104
- // 确保归档目录存在
105
- if (!fs.existsSync(archivesDir)) {
106
- await fsAsync.mkdir(archivesDir, { recursive: true });
107
- }
108
-
109
- // 拷贝需求目录到归档目录
110
- const sourceDir = path.join(changesDir, requirementName);
111
- Ec.waiting(`正在归档需求 "${requirementName}" 到 "${archiveDir}"`);
112
- await _copyDir(sourceDir, archiveDir);
113
-
114
- // 删除原始需求目录
115
- Ec.waiting(`正在删除原始需求目录 "${sourceDir}"`);
116
- await _removeDir(sourceDir);
117
-
118
- Ec.info(`✅ 成功归档需求 "${requirementName}" 为 "${archiveName}"`);
119
- process.exit(0);
120
- } catch (error) {
121
- Ec.error(`❌ 执行过程中发生错误: ${error.message}`);
122
- process.exit(1);
123
- }
124
- };
@@ -1,202 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { exec } = require('child_process');
4
- const util = require('util');
5
- const Ec = require('../epic');
6
-
7
- // 将 exec 转换为 Promise 版本
8
- const execAsync = util.promisify(exec);
9
-
10
- /**
11
- * 检查目录是否为 Git 仓库
12
- * @param {string} dirPath 目录路径
13
- * @returns {Promise<boolean>} 是否为 Git 仓库
14
- */
15
- const _isGitRepo = async (dirPath) => {
16
- try {
17
- await execAsync('git rev-parse --git-dir', { cwd: dirPath });
18
- return true;
19
- } catch (error) {
20
- return false;
21
- }
22
- };
23
-
24
- /**
25
- * 检查是否有更改需要提交
26
- * @param {string} dirPath 目录路径
27
- * @returns {Promise<boolean>} 是否有更改
28
- */
29
- const _hasChanges = async (dirPath) => {
30
- try {
31
- const { stdout } = await execAsync('git status --porcelain', { cwd: dirPath });
32
- return stdout.trim() !== '';
33
- } catch (error) {
34
- return false;
35
- }
36
- };
37
-
38
- /**
39
- * 添加所有更改
40
- * @param {string} dirPath 目录路径
41
- */
42
- const _addAllChanges = async (dirPath) => {
43
- try {
44
- Ec.waiting(`正在添加更改: ${dirPath}`);
45
- const { stdout, stderr } = await execAsync('git add .', { cwd: dirPath });
46
-
47
- if (stdout) {
48
- Ec.waiting(`输出: ${stdout.trim()}`);
49
- }
50
- if (stderr) {
51
- Ec.waiting(`进度: ${stderr.trim()}`);
52
- }
53
-
54
- Ec.waiting(`✅ 成功添加更改: ${dirPath}`);
55
- } catch (error) {
56
- Ec.error(`❌ 添加更改失败 ${dirPath}: ${error.message}`);
57
- throw error;
58
- }
59
- };
60
-
61
- /**
62
- * 提交更改
63
- * @param {string} dirPath 目录路径
64
- * @param {string} message 提交信息
65
- */
66
- const _commitChanges = async (dirPath, message) => {
67
- try {
68
- Ec.waiting(`正在提交更改: ${dirPath}`);
69
- const command = `git commit -m "${message}"`;
70
- const { stdout, stderr } = await execAsync(command, { cwd: dirPath });
71
-
72
- if (stdout) {
73
- Ec.waiting(`输出: ${stdout.trim()}`);
74
- }
75
- if (stderr) {
76
- Ec.waiting(`进度: ${stderr.trim()}`);
77
- }
78
-
79
- Ec.waiting(`✅ 成功提交更改: ${dirPath}`);
80
- } catch (error) {
81
- // 检查是否是因为没有更改导致的错误
82
- if (error.message.includes('nothing to commit')) {
83
- Ec.waiting(`⚠️ ${dirPath} 没有需要提交的更改`);
84
- } else {
85
- Ec.error(`❌ 提交更改失败 ${dirPath}: ${error.message}`);
86
- throw error;
87
- }
88
- }
89
- };
90
-
91
- /**
92
- * 提交 submodule 更改
93
- * @param {string} dirPath 目录路径
94
- * @param {string} message 提交信息
95
- */
96
- const _commitSubmodules = async (dirPath, message) => {
97
- try {
98
- Ec.waiting(`正在提交 Submodule 更改: ${dirPath}`);
99
- // 添加 submodule 更改
100
- await execAsync('git add .', { cwd: dirPath });
101
- // 提交更改
102
- const command = `git commit -m "${message}"`;
103
- const { stdout, stderr } = await execAsync(command, { cwd: dirPath });
104
-
105
- if (stdout) {
106
- Ec.waiting(`输出: ${stdout.trim()}`);
107
- }
108
- if (stderr) {
109
- Ec.waiting(`进度: ${stderr.trim()}`);
110
- }
111
-
112
- Ec.waiting(`✅ 成功提交 Submodule 更改: ${dirPath}`);
113
- } catch (error) {
114
- // 检查是否是因为没有更改导致的错误
115
- if (error.message.includes('nothing to commit')) {
116
- Ec.waiting(`⚠️ ${dirPath} Submodule 没有需要提交的更改`);
117
- } else {
118
- Ec.error(`❌ 提交 Submodule 更改失败 ${dirPath}: ${error.message}`);
119
- throw error;
120
- }
121
- }
122
- };
123
-
124
- module.exports = async (options) => {
125
- // 参数提取
126
- const parsed = Ec.parseArgument(options);
127
- const message = parsed.message || parsed.m;
128
-
129
- // 验证参数
130
- if (!message) {
131
- Ec.error("❌ 请提供提交信息 (-m, --message)");
132
- process.exit(1);
133
- }
134
-
135
- try {
136
- // 获取 source 目录路径
137
- const sourceDir = path.resolve(process.cwd(), 'source');
138
-
139
- // 检查 source 目录是否存在
140
- if (!fs.existsSync(sourceDir)) {
141
- Ec.error("❌ 未找到 source 目录");
142
- process.exit(1);
143
- }
144
-
145
- // 获取所有 develop-xx 目录
146
- const files = fs.readdirSync(sourceDir);
147
- const developDirs = files.filter(file =>
148
- fs.statSync(path.join(sourceDir, file)).isDirectory() &&
149
- file.match(/^develop-\d+$/)
150
- ).sort();
151
-
152
- if (developDirs.length === 0) {
153
- Ec.waiting("🔍 未找到任何 develop 副本目录");
154
- process.exit(0);
155
- }
156
-
157
- Ec.waiting(`共找到 ${developDirs.length} 个 develop 副本目录`);
158
-
159
- // 遍历所有 develop 目录并提交更改
160
- for (const dir of developDirs) {
161
- const fullPath = path.join(sourceDir, dir);
162
-
163
- // 添加分割线
164
- Ec.waiting("--------------------------------------------------");
165
-
166
- // 检查是否为 Git 仓库
167
- const isGitRepo = await _isGitRepo(fullPath);
168
- if (!isGitRepo) {
169
- Ec.waiting(`⚠️ ${fullPath} 不是 Git 仓库,跳过`);
170
- continue;
171
- }
172
-
173
- // 检查是否有更改
174
- const hasChange = await _hasChanges(fullPath);
175
- if (!hasChange) {
176
- Ec.waiting(`⚠️ ${fullPath} 没有需要提交的更改`);
177
- continue;
178
- }
179
-
180
- // 添加并提交更改
181
- await _addAllChanges(fullPath);
182
- await _commitChanges(fullPath, message);
183
- }
184
-
185
- // 添加分割线
186
- Ec.waiting("--------------------------------------------------");
187
-
188
- // 提交主仓库的 submodule 更新
189
- const hasSubmoduleChanges = await _hasChanges(process.cwd());
190
- if (hasSubmoduleChanges) {
191
- await _commitSubmodules(process.cwd(), `Update submodules: ${message}`);
192
- } else {
193
- Ec.waiting("⚠️ 主仓库没有 submodule 更改需要提交");
194
- }
195
-
196
- Ec.info('✅ 所有副本更改提交完成!');
197
- process.exit(0);
198
- } catch (error) {
199
- Ec.error(`❌ 执行过程中发生错误: ${error.message}`);
200
- process.exit(1);
201
- }
202
- };
@@ -1,142 +0,0 @@
1
- /**
2
- * 执行 console 命令 - 启动交互式控制台
3
- */
4
-
5
- const readline = require('readline');
6
- const colors = require('colors');
7
- const path = require('path');
8
- const fs = require('fs');
9
- const terminalCommands = require('../terminal');
10
-
11
- // 设置颜色主题
12
- colors.setTheme({
13
- silly: 'rainbow',
14
- input: 'grey',
15
- verbose: 'cyan',
16
- prompt: 'red',
17
- info: 'green',
18
- data: 'blue',
19
- help: 'cyan',
20
- warn: 'yellow',
21
- debug: 'magenta',
22
- error: 'red'
23
- });
24
-
25
- // 显示欢迎界面和菜单
26
- const showMenu = () => {
27
- // 清屏
28
- process.stdout.write('\x1Bc');
29
-
30
- // 显示标准头部信息
31
- showHeader();
32
-
33
- // 使用96个字符宽度
34
- const width = 96;
35
- const headerBorder = '='.repeat(width).blue;
36
- const footerBorder = '-'.repeat(width).blue;
37
-
38
- console.log('');
39
- console.log(headerBorder);
40
- const title = 'Momo AI / Lain Console';
41
- const padding = ' '.repeat(Math.floor((width - title.length) / 2) - 1);
42
- console.log(`${padding}${title}`.bold.brightCyan);
43
- console.log(headerBorder);
44
-
45
- console.log('');
46
- console.log('欢迎使用 Momo AI / Lain 控制台!'.green);
47
- console.log('这是一个交互式命令行界面。'.yellow);
48
- console.log('');
49
-
50
- console.log('可用命令:'.bold);
51
- console.log(' help - 显示帮助信息'.white);
52
- console.log(' llm - 查看大模型配置信息'.white);
53
- console.log(' quit - 退出控制台'.white);
54
- console.log('');
55
-
56
- console.log('请在提示符后输入命令。'.gray);
57
- console.log(footerBorder);
58
- };
59
-
60
- // 显示标准头部信息
61
- const showHeader = () => {
62
- const appInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../package.json'), 'utf8'));
63
-
64
- console.log(`[Momo AI]`.green.bold + ` ----------------- Rachel Momo / AI工具项 ------------------`.rainbow);
65
- console.log(`[Momo AI]`.green.bold + ' 应用名称: '.bold + 'Rachel Momo / SDD');
66
- console.log(`[Momo AI]`.green.bold + ' 工具主页: '.bold + appInfo.homepage.blue);
67
- console.log(`[Momo AI]`.green.bold + ` 工具版本: ` + `${appInfo.version}`.red + ' ' + `( Node >= 22.x )`.yellow);
68
- console.log(`[Momo AI]`.green.bold);
69
- console.log(`[Momo AI]`.green.bold + ` ----------------- AI 系统启动…… ----------------------------`.rainbow);
70
- };
71
-
72
- // 处理用户输入
73
- const handleInput = (input, commands) => {
74
- const command = input.trim().toLowerCase();
75
-
76
- // 创建命令上下文
77
- const context = {
78
- commands: commands
79
- };
80
-
81
- switch (command) {
82
- case '':
83
- // 空命令,不处理
84
- break;
85
- case 'help':
86
- commands.help(context);
87
- break;
88
- case 'llm':
89
- commands.llm(context);
90
- break;
91
- case 'quit':
92
- commands.quit(context);
93
- break;
94
- default:
95
- console.log('');
96
- console.log(`未知命令: ${command}`.brightRed);
97
- console.log('输入 "help" 查看可用命令。'.yellow);
98
- console.log('');
99
- }
100
- };
101
-
102
- // 主函数
103
- const executeConsole = async () => {
104
- showMenu();
105
-
106
- // 先关闭全局的 readline 接口,避免冲突
107
- try {
108
- const globalRl = require('../epic/momo.fn.log');
109
- if (globalRl.askClose) {
110
- globalRl.askClose();
111
- }
112
- } catch (e) {
113
- // 忽略错误
114
- }
115
-
116
- // 创建 readline 接口
117
- const rl = readline.createInterface({
118
- input: process.stdin,
119
- output: process.stdout,
120
- prompt: '[Lain AI] > '.cyan.bold
121
- });
122
-
123
- rl.prompt();
124
-
125
- rl.on('line', (line) => {
126
- const input = line.trim();
127
- handleInput(input, terminalCommands);
128
- rl.prompt();
129
- }).on('close', () => {
130
- console.log('\n' + '感谢使用 Momo AI / Lain 控制台,再见!'.brightGreen + '\n');
131
- process.exit(0);
132
- });
133
-
134
- // 处理 Ctrl+C
135
- process.on('SIGINT', () => {
136
- console.log('\n\n' + '感谢使用 Momo AI / Lain 控制台,再见!'.brightGreen + '\n');
137
- rl.close();
138
- process.exit(0);
139
- });
140
- };
141
-
142
- module.exports = executeConsole;