@zeyue0329/xiaoma-cli 1.0.37 β†’ 1.0.39

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 (89) hide show
  1. package/.idea/workspace.xml +27 -26
  2. package/JAVA-BACKEND-COMMANDS-REFERENCE.md +62 -52
  3. package/JAVA-BACKEND-ITERATION-GUIDE.md +125 -18
  4. package/README.md +1 -1
  5. package/common/utils/bmad-doc-template.md +5 -5
  6. package/dist/agents/analyst.txt +35 -5
  7. package/dist/agents/architect.txt +217 -31
  8. package/dist/agents/automation-orchestrator.txt +4 -4
  9. package/dist/agents/dev.txt +3 -3
  10. package/dist/agents/full-requirement-orchestrator.txt +11 -11
  11. package/dist/agents/qa.txt +102 -102
  12. package/dist/agents/sm.txt +6 -6
  13. package/dist/agents/ux-expert.txt +6 -1
  14. package/dist/agents/workflow-executor.txt +879 -0
  15. package/dist/agents/xiaoma-master.txt +258 -37
  16. package/dist/teams/team-all.txt +1223 -445
  17. package/dist/teams/team-fullstack-with-database.txt +384 -446
  18. package/dist/teams/team-fullstack.txt +258 -37
  19. package/dist/teams/team-ide-minimal.txt +111 -111
  20. package/dist/teams/team-no-ui.txt +252 -36
  21. package/docs/architecture-sharding-modification.md +623 -0
  22. package/docs/automated-requirements-analysis-outputs.md +896 -0
  23. package/package.json +1 -1
  24. package/tools/builders/web-builder.js +292 -142
  25. package/tools/bump-all-versions.js +50 -32
  26. package/tools/cli.js +52 -47
  27. package/tools/flattener/aggregate.js +30 -12
  28. package/tools/flattener/binary.js +46 -43
  29. package/tools/flattener/discovery.js +23 -15
  30. package/tools/flattener/files.js +6 -6
  31. package/tools/flattener/ignoreRules.js +122 -121
  32. package/tools/flattener/main.js +249 -144
  33. package/tools/flattener/projectRoot.js +74 -69
  34. package/tools/flattener/prompts.js +12 -10
  35. package/tools/flattener/stats.helpers.js +90 -61
  36. package/tools/flattener/stats.js +1 -1
  37. package/tools/flattener/test-matrix.js +225 -170
  38. package/tools/flattener/xml.js +31 -23
  39. package/tools/installer/bin/xiaoma.js +199 -153
  40. package/tools/installer/lib/config-loader.js +76 -47
  41. package/tools/installer/lib/file-manager.js +101 -44
  42. package/tools/installer/lib/ide-base-setup.js +49 -39
  43. package/tools/installer/lib/ide-setup.js +694 -380
  44. package/tools/installer/lib/installer.js +802 -469
  45. package/tools/installer/lib/memory-profiler.js +22 -12
  46. package/tools/installer/lib/module-manager.js +16 -14
  47. package/tools/installer/lib/resource-locator.js +61 -35
  48. package/tools/lib/dependency-resolver.js +34 -23
  49. package/tools/lib/yaml-utils.js +7 -2
  50. package/tools/preview-release-notes.js +33 -25
  51. package/tools/shared/bannerArt.js +3 -3
  52. package/tools/sync-installer-version.js +16 -7
  53. package/tools/upgraders/v3-to-v4-upgrader.js +244 -163
  54. package/tools/version-bump.js +24 -18
  55. package/tools/xiaoma-npx-wrapper.js +15 -10
  56. package/tools/yaml-format.js +60 -36
  57. package/xiaoma-core/agent-teams/team-fullstack-with-database.yaml +0 -1
  58. package/xiaoma-core/agents/automated-fix-validator.yaml +2 -1
  59. package/xiaoma-core/agents/automated-quality-validator.yaml +10 -5
  60. package/xiaoma-core/agents/automation-orchestrator.md +4 -4
  61. package/xiaoma-core/agents/dev.md +4 -4
  62. package/xiaoma-core/agents/enhanced-workflow-orchestrator.yaml +2 -1
  63. package/xiaoma-core/agents/full-requirement-orchestrator.md +11 -11
  64. package/xiaoma-core/agents/global-requirements-auditor.yaml +11 -3
  65. package/xiaoma-core/agents/intelligent-template-adapter.yaml +19 -5
  66. package/xiaoma-core/agents/master-execution-engine.yaml +19 -5
  67. package/xiaoma-core/agents/workflow-executor.md +8 -4
  68. package/xiaoma-core/agents/xiaoma-master.md +1 -1
  69. package/xiaoma-core/data/test-levels-framework.md +12 -12
  70. package/xiaoma-core/tasks/analyze-existing-database.md +1 -1
  71. package/xiaoma-core/tasks/apply-qa-fixes.md +3 -3
  72. package/xiaoma-core/tasks/batch-story-generation.md +22 -22
  73. package/xiaoma-core/tasks/create-enhanced-story-with-database.md +6 -6
  74. package/xiaoma-core/tasks/nfr-assess.md +6 -6
  75. package/xiaoma-core/tasks/project-integration-testing.md +42 -42
  76. package/xiaoma-core/tasks/qa-gate.md +23 -23
  77. package/xiaoma-core/tasks/review-story.md +18 -18
  78. package/xiaoma-core/tasks/risk-profile.md +25 -25
  79. package/xiaoma-core/tasks/serial-development-orchestration.md +51 -51
  80. package/xiaoma-core/tasks/test-design.md +9 -9
  81. package/xiaoma-core/tasks/trace-requirements.md +21 -21
  82. package/xiaoma-core/templates/competitor-analysis-tmpl.yaml +35 -5
  83. package/xiaoma-core/templates/front-end-architecture-tmpl.yaml +77 -11
  84. package/xiaoma-core/templates/front-end-spec-tmpl.yaml +6 -1
  85. package/xiaoma-core/templates/fullstack-architecture-tmpl.yaml +140 -20
  86. package/xiaoma-core/templates/global-qa-monitoring-tmpl.yaml +2 -1
  87. package/xiaoma-core/templates/requirements-coverage-audit.yaml +2 -1
  88. package/xiaoma-core/workflows/automated-requirements-analysis.yaml +283 -6
  89. package/dist/agents/database-architect.txt +0 -322
@@ -3,7 +3,7 @@
3
3
  * Helps identify memory leaks and optimize resource usage
4
4
  */
5
5
 
6
- const v8 = require('node:v8');
6
+ const v8 = require("node:v8");
7
7
 
8
8
  class MemoryProfiler {
9
9
  constructor() {
@@ -134,9 +134,11 @@ class MemoryProfiler {
134
134
 
135
135
  if (largeGrowths.length > 0) {
136
136
  recommendations.push({
137
- type: 'warning',
137
+ type: "warning",
138
138
  message: `Large memory growth detected in ${largeGrowths.length} operations`,
139
- details: largeGrowths.map((g) => `${g.from} β†’ ${g.to}: ${g.heapGrowth}`),
139
+ details: largeGrowths.map(
140
+ (g) => `${g.from} β†’ ${g.to}: ${g.heapGrowth}`,
141
+ ),
140
142
  });
141
143
  }
142
144
 
@@ -144,9 +146,9 @@ class MemoryProfiler {
144
146
  if (this.peakMemory > 500 * 1024 * 1024) {
145
147
  // 500MB
146
148
  recommendations.push({
147
- type: 'warning',
149
+ type: "warning",
148
150
  message: `High peak memory usage: ${this.formatBytes(this.peakMemory)}`,
149
- suggestion: 'Consider processing files in smaller batches',
151
+ suggestion: "Consider processing files in smaller batches",
150
152
  });
151
153
  }
152
154
 
@@ -154,9 +156,10 @@ class MemoryProfiler {
154
156
  const continuousGrowth = this.checkContinuousGrowth();
155
157
  if (continuousGrowth) {
156
158
  recommendations.push({
157
- type: 'error',
158
- message: 'Potential memory leak detected',
159
- details: 'Memory usage continuously increases without significant decreases',
159
+ type: "error",
160
+ message: "Potential memory leak detected",
161
+ details:
162
+ "Memory usage continuously increases without significant decreases",
160
163
  });
161
164
  }
162
165
 
@@ -171,7 +174,10 @@ class MemoryProfiler {
171
174
 
172
175
  let increasingCount = 0;
173
176
  for (let index = 1; index < this.checkpoints.length; index++) {
174
- if (this.checkpoints[index].raw.heapUsed > this.checkpoints[index - 1].raw.heapUsed) {
177
+ if (
178
+ this.checkpoints[index].raw.heapUsed >
179
+ this.checkpoints[index - 1].raw.heapUsed
180
+ ) {
175
181
  increasingCount++;
176
182
  }
177
183
  }
@@ -184,13 +190,17 @@ class MemoryProfiler {
184
190
  * Format bytes to human-readable string
185
191
  */
186
192
  formatBytes(bytes) {
187
- if (bytes === 0) return '0 B';
193
+ if (bytes === 0) return "0 B";
188
194
 
189
195
  const k = 1024;
190
- const sizes = ['B', 'KB', 'MB', 'GB'];
196
+ const sizes = ["B", "KB", "MB", "GB"];
191
197
  const index = Math.floor(Math.log(bytes) / Math.log(k));
192
198
 
193
- return Number.parseFloat((bytes / Math.pow(k, index)).toFixed(2)) + ' ' + sizes[index];
199
+ return (
200
+ Number.parseFloat((bytes / Math.pow(k, index)).toFixed(2)) +
201
+ " " +
202
+ sizes[index]
203
+ );
194
204
  }
195
205
 
196
206
  /**
@@ -15,9 +15,9 @@ class ModuleManager {
15
15
  */
16
16
  async initializeCommonModules() {
17
17
  const modules = await Promise.all([
18
- this.getModule('chalk'),
19
- this.getModule('ora'),
20
- this.getModule('inquirer'),
18
+ this.getModule("chalk"),
19
+ this.getModule("ora"),
20
+ this.getModule("inquirer"),
21
21
  ]);
22
22
 
23
23
  return {
@@ -64,20 +64,20 @@ class ModuleManager {
64
64
  */
65
65
  async _loadModule(moduleName) {
66
66
  switch (moduleName) {
67
- case 'chalk': {
68
- return (await import('chalk')).default;
67
+ case "chalk": {
68
+ return (await import("chalk")).default;
69
69
  }
70
- case 'ora': {
71
- return (await import('ora')).default;
70
+ case "ora": {
71
+ return (await import("ora")).default;
72
72
  }
73
- case 'inquirer': {
74
- return (await import('inquirer')).default;
73
+ case "inquirer": {
74
+ return (await import("inquirer")).default;
75
75
  }
76
- case 'glob': {
77
- return (await import('glob')).glob;
76
+ case "glob": {
77
+ return (await import("glob")).glob;
78
78
  }
79
- case 'globSync': {
80
- return (await import('glob')).globSync;
79
+ case "globSync": {
80
+ return (await import("glob")).globSync;
81
81
  }
82
82
  default: {
83
83
  throw new Error(`Unknown module: ${moduleName}`);
@@ -99,7 +99,9 @@ class ModuleManager {
99
99
  * @returns {Promise<Object>} Object with module names as keys
100
100
  */
101
101
  async getModules(moduleNames) {
102
- const modules = await Promise.all(moduleNames.map((name) => this.getModule(name)));
102
+ const modules = await Promise.all(
103
+ moduleNames.map((name) => this.getModule(name)),
104
+ );
103
105
 
104
106
  return moduleNames.reduce((accumulator, name, index) => {
105
107
  accumulator[name] = modules[index];
@@ -3,9 +3,9 @@
3
3
  * Reduces duplicate file system operations and memory usage
4
4
  */
5
5
 
6
- const path = require('node:path');
7
- const fs = require('fs-extra');
8
- const moduleManager = require('./module-manager');
6
+ const path = require("node:path");
7
+ const fs = require("fs-extra");
8
+ const moduleManager = require("./module-manager");
9
9
 
10
10
  class ResourceLocator {
11
11
  constructor() {
@@ -20,7 +20,7 @@ class ResourceLocator {
20
20
  */
21
21
  getBmadCorePath() {
22
22
  if (!this._bmadCorePath) {
23
- this._bmadCorePath = path.join(__dirname, '../../../xiaoma-core');
23
+ this._bmadCorePath = path.join(__dirname, "../../../xiaoma-core");
24
24
  }
25
25
  return this._bmadCorePath;
26
26
  }
@@ -30,7 +30,10 @@ class ResourceLocator {
30
30
  */
31
31
  getExpansionPacksPath() {
32
32
  if (!this._expansionPacksPath) {
33
- this._expansionPacksPath = path.join(__dirname, '../../../expansion-packs');
33
+ this._expansionPacksPath = path.join(
34
+ __dirname,
35
+ "../../../expansion-packs",
36
+ );
34
37
  }
35
38
  return this._expansionPacksPath;
36
39
  }
@@ -48,7 +51,7 @@ class ResourceLocator {
48
51
  return this._globCache.get(cacheKey);
49
52
  }
50
53
 
51
- const { glob } = await moduleManager.getModules(['glob']);
54
+ const { glob } = await moduleManager.getModules(["glob"]);
52
55
  const files = await glob(pattern, options);
53
56
 
54
57
  // Cache for 5 minutes
@@ -71,7 +74,11 @@ class ResourceLocator {
71
74
  }
72
75
 
73
76
  // Check in xiaoma-core
74
- let agentPath = path.join(this.getBmadCorePath(), 'agents', `${agentId}.md`);
77
+ let agentPath = path.join(
78
+ this.getBmadCorePath(),
79
+ "agents",
80
+ `${agentId}.md`,
81
+ );
75
82
  if (await fs.pathExists(agentPath)) {
76
83
  this._pathCache.set(cacheKey, agentPath);
77
84
  return agentPath;
@@ -80,7 +87,7 @@ class ResourceLocator {
80
87
  // Check in expansion packs
81
88
  const expansionPacks = await this.getExpansionPacks();
82
89
  for (const pack of expansionPacks) {
83
- agentPath = path.join(pack.path, 'agents', `${agentId}.md`);
90
+ agentPath = path.join(pack.path, "agents", `${agentId}.md`);
84
91
  if (await fs.pathExists(agentPath)) {
85
92
  this._pathCache.set(cacheKey, agentPath);
86
93
  return agentPath;
@@ -95,32 +102,35 @@ class ResourceLocator {
95
102
  * @returns {Promise<Array>} Array of agent objects
96
103
  */
97
104
  async getAvailableAgents() {
98
- const cacheKey = 'all-agents';
105
+ const cacheKey = "all-agents";
99
106
 
100
107
  if (this._pathCache.has(cacheKey)) {
101
108
  return this._pathCache.get(cacheKey);
102
109
  }
103
110
 
104
111
  const agents = [];
105
- const yaml = require('js-yaml');
106
- const { extractYamlFromAgent } = require('../../lib/yaml-utils');
112
+ const yaml = require("js-yaml");
113
+ const { extractYamlFromAgent } = require("../../lib/yaml-utils");
107
114
 
108
115
  // Get agents from xiaoma-core
109
- const coreAgents = await this.findFiles('agents/*.md', {
116
+ const coreAgents = await this.findFiles("agents/*.md", {
110
117
  cwd: this.getBmadCorePath(),
111
118
  });
112
119
 
113
120
  for (const agentFile of coreAgents) {
114
- const content = await fs.readFile(path.join(this.getBmadCorePath(), agentFile), 'utf8');
121
+ const content = await fs.readFile(
122
+ path.join(this.getBmadCorePath(), agentFile),
123
+ "utf8",
124
+ );
115
125
  const yamlContent = extractYamlFromAgent(content);
116
126
  if (yamlContent) {
117
127
  try {
118
128
  const metadata = yaml.load(yamlContent);
119
129
  agents.push({
120
- id: path.basename(agentFile, '.md'),
121
- name: metadata.agent_name || path.basename(agentFile, '.md'),
122
- description: metadata.description || 'No description available',
123
- source: 'core',
130
+ id: path.basename(agentFile, ".md"),
131
+ name: metadata.agent_name || path.basename(agentFile, ".md"),
132
+ description: metadata.description || "No description available",
133
+ source: "core",
124
134
  });
125
135
  } catch {
126
136
  // Skip invalid agents
@@ -140,7 +150,7 @@ class ResourceLocator {
140
150
  * @returns {Promise<Array>} Array of expansion pack objects
141
151
  */
142
152
  async getExpansionPacks() {
143
- const cacheKey = 'expansion-packs';
153
+ const cacheKey = "expansion-packs";
144
154
 
145
155
  if (this._pathCache.has(cacheKey)) {
146
156
  return this._pathCache.get(cacheKey);
@@ -150,23 +160,31 @@ class ResourceLocator {
150
160
  const expansionPacksPath = this.getExpansionPacksPath();
151
161
 
152
162
  if (await fs.pathExists(expansionPacksPath)) {
153
- const entries = await fs.readdir(expansionPacksPath, { withFileTypes: true });
163
+ const entries = await fs.readdir(expansionPacksPath, {
164
+ withFileTypes: true,
165
+ });
154
166
 
155
167
  for (const entry of entries) {
156
168
  if (entry.isDirectory()) {
157
- const configPath = path.join(expansionPacksPath, entry.name, 'config.yaml');
169
+ const configPath = path.join(
170
+ expansionPacksPath,
171
+ entry.name,
172
+ "config.yaml",
173
+ );
158
174
  if (await fs.pathExists(configPath)) {
159
175
  try {
160
- const yaml = require('js-yaml');
161
- const config = yaml.load(await fs.readFile(configPath, 'utf8'));
176
+ const yaml = require("js-yaml");
177
+ const config = yaml.load(await fs.readFile(configPath, "utf8"));
162
178
  packs.push({
163
179
  id: entry.name,
164
180
  name: config.name || entry.name,
165
- version: config.version || '1.0.0',
166
- description: config.description || 'No description available',
181
+ version: config.version || "1.0.0",
182
+ description: config.description || "No description available",
167
183
  shortTitle:
168
- config['short-title'] || config.description || 'No description available',
169
- author: config.author || 'Unknown',
184
+ config["short-title"] ||
185
+ config.description ||
186
+ "No description available",
187
+ author: config.author || "Unknown",
170
188
  path: path.join(expansionPacksPath, entry.name),
171
189
  });
172
190
  } catch {
@@ -196,12 +214,16 @@ class ResourceLocator {
196
214
  return this._pathCache.get(cacheKey);
197
215
  }
198
216
 
199
- const teamPath = path.join(this.getBmadCorePath(), 'agent-teams', `${teamId}.yaml`);
217
+ const teamPath = path.join(
218
+ this.getBmadCorePath(),
219
+ "agent-teams",
220
+ `${teamId}.yaml`,
221
+ );
200
222
 
201
223
  if (await fs.pathExists(teamPath)) {
202
224
  try {
203
- const yaml = require('js-yaml');
204
- const content = await fs.readFile(teamPath, 'utf8');
225
+ const yaml = require("js-yaml");
226
+ const content = await fs.readFile(teamPath, "utf8");
205
227
  const config = yaml.load(content);
206
228
  this._pathCache.set(cacheKey, config);
207
229
  return config;
@@ -230,8 +252,8 @@ class ResourceLocator {
230
252
  return { all: [], byType: {} };
231
253
  }
232
254
 
233
- const content = await fs.readFile(agentPath, 'utf8');
234
- const { extractYamlFromAgent } = require('../../lib/yaml-utils');
255
+ const content = await fs.readFile(agentPath, "utf8");
256
+ const { extractYamlFromAgent } = require("../../lib/yaml-utils");
235
257
  const yamlContent = extractYamlFromAgent(content);
236
258
 
237
259
  if (!yamlContent) {
@@ -239,7 +261,7 @@ class ResourceLocator {
239
261
  }
240
262
 
241
263
  try {
242
- const yaml = require('js-yaml');
264
+ const yaml = require("js-yaml");
243
265
  const metadata = yaml.load(yamlContent);
244
266
  const dependencies = metadata.dependencies || {};
245
267
 
@@ -284,12 +306,16 @@ class ResourceLocator {
284
306
  return this._pathCache.get(cacheKey);
285
307
  }
286
308
 
287
- const idePath = path.join(this.getBmadCorePath(), 'ide-rules', `${ideId}.yaml`);
309
+ const idePath = path.join(
310
+ this.getBmadCorePath(),
311
+ "ide-rules",
312
+ `${ideId}.yaml`,
313
+ );
288
314
 
289
315
  if (await fs.pathExists(idePath)) {
290
316
  try {
291
- const yaml = require('js-yaml');
292
- const content = await fs.readFile(idePath, 'utf8');
317
+ const yaml = require("js-yaml");
318
+ const content = await fs.readFile(idePath, "utf8");
293
319
  const config = yaml.load(content);
294
320
  this._pathCache.set(cacheKey, config);
295
321
  return config;
@@ -1,19 +1,19 @@
1
- const fs = require('node:fs').promises;
2
- const path = require('node:path');
3
- const yaml = require('js-yaml');
4
- const { extractYamlFromAgent } = require('./yaml-utils');
1
+ const fs = require("node:fs").promises;
2
+ const path = require("node:path");
3
+ const yaml = require("js-yaml");
4
+ const { extractYamlFromAgent } = require("./yaml-utils");
5
5
 
6
6
  class DependencyResolver {
7
7
  constructor(rootDir) {
8
8
  this.rootDir = rootDir;
9
- this.xiaomaCore = path.join(rootDir, 'xiaoma-core');
10
- this.common = path.join(rootDir, 'common');
9
+ this.xiaomaCore = path.join(rootDir, "xiaoma-core");
10
+ this.common = path.join(rootDir, "common");
11
11
  this.cache = new Map();
12
12
  }
13
13
 
14
14
  async resolveAgentDependencies(agentId) {
15
- const agentPath = path.join(this.xiaomaCore, 'agents', `${agentId}.md`);
16
- const agentContent = await fs.readFile(agentPath, 'utf8');
15
+ const agentPath = path.join(this.xiaomaCore, "agents", `${agentId}.md`);
16
+ const agentContent = await fs.readFile(agentPath, "utf8");
17
17
 
18
18
  // Extract YAML from markdown content with command cleaning
19
19
  const yamlContent = extractYamlFromAgent(agentContent, true);
@@ -36,7 +36,7 @@ class DependencyResolver {
36
36
  // Personas are now embedded in agent configs, no need to resolve separately
37
37
 
38
38
  // Resolve other dependencies
39
- const depTypes = ['tasks', 'templates', 'checklists', 'data', 'utils'];
39
+ const depTypes = ["tasks", "templates", "checklists", "data", "utils"];
40
40
  for (const depType of depTypes) {
41
41
  const deps = agentConfig.dependencies?.[depType] || [];
42
42
  for (const depId of deps) {
@@ -49,8 +49,12 @@ class DependencyResolver {
49
49
  }
50
50
 
51
51
  async resolveTeamDependencies(teamId) {
52
- const teamPath = path.join(this.xiaomaCore, 'agent-teams', `${teamId}.yaml`);
53
- const teamContent = await fs.readFile(teamPath, 'utf8');
52
+ const teamPath = path.join(
53
+ this.xiaomaCore,
54
+ "agent-teams",
55
+ `${teamId}.yaml`,
56
+ );
57
+ const teamContent = await fs.readFile(teamPath, "utf8");
54
58
  const teamConfig = yaml.load(teamContent);
55
59
 
56
60
  const dependencies = {
@@ -65,7 +69,9 @@ class DependencyResolver {
65
69
  };
66
70
 
67
71
  // Always add xiaoma-orchestrator agent first if it's a team
68
- const bmadAgent = await this.resolveAgentDependencies('xiaoma-orchestrator');
72
+ const bmadAgent = await this.resolveAgentDependencies(
73
+ "xiaoma-orchestrator",
74
+ );
69
75
  dependencies.agents.push(bmadAgent.agent);
70
76
  for (const res of bmadAgent.resources) {
71
77
  dependencies.resources.set(res.path, res);
@@ -75,19 +81,20 @@ class DependencyResolver {
75
81
  let agentsToResolve = teamConfig.agents || [];
76
82
 
77
83
  // Handle wildcard "*" - include all agents except xiaoma-master
78
- if (agentsToResolve.includes('*')) {
84
+ if (agentsToResolve.includes("*")) {
79
85
  const allAgents = await this.listAgents();
80
86
  // Remove wildcard and add all agents except those already in the list and xiaoma-master
81
- agentsToResolve = agentsToResolve.filter((a) => a !== '*');
87
+ agentsToResolve = agentsToResolve.filter((a) => a !== "*");
82
88
  for (const agent of allAgents) {
83
- if (!agentsToResolve.includes(agent) && agent !== 'xiaoma-master') {
89
+ if (!agentsToResolve.includes(agent) && agent !== "xiaoma-master") {
84
90
  agentsToResolve.push(agent);
85
91
  }
86
92
  }
87
93
  }
88
94
 
89
95
  for (const agentId of agentsToResolve) {
90
- if (agentId === 'xiaoma-orchestrator' || agentId === 'xiaoma-master') continue; // Already added or excluded
96
+ if (agentId === "xiaoma-orchestrator" || agentId === "xiaoma-master")
97
+ continue; // Already added or excluded
91
98
  const agentDeps = await this.resolveAgentDependencies(agentId);
92
99
  dependencies.agents.push(agentDeps.agent);
93
100
 
@@ -99,7 +106,7 @@ class DependencyResolver {
99
106
 
100
107
  // Resolve workflows
101
108
  for (const workflowId of teamConfig.workflows || []) {
102
- const resource = await this.loadResource('workflows', workflowId);
109
+ const resource = await this.loadResource("workflows", workflowId);
103
110
  if (resource) dependencies.resources.set(resource.path, resource);
104
111
  }
105
112
 
@@ -122,12 +129,12 @@ class DependencyResolver {
122
129
  // First try xiaoma-core
123
130
  try {
124
131
  filePath = path.join(this.xiaomaCore, type, id);
125
- content = await fs.readFile(filePath, 'utf8');
132
+ content = await fs.readFile(filePath, "utf8");
126
133
  } catch {
127
134
  // If not found in xiaoma-core, try common folder
128
135
  try {
129
136
  filePath = path.join(this.common, type, id);
130
- content = await fs.readFile(filePath, 'utf8');
137
+ content = await fs.readFile(filePath, "utf8");
131
138
  } catch {
132
139
  // File not found in either location
133
140
  }
@@ -155,8 +162,10 @@ class DependencyResolver {
155
162
 
156
163
  async listAgents() {
157
164
  try {
158
- const files = await fs.readdir(path.join(this.xiaomaCore, 'agents'));
159
- return files.filter((f) => f.endsWith('.md')).map((f) => f.replace('.md', ''));
165
+ const files = await fs.readdir(path.join(this.xiaomaCore, "agents"));
166
+ return files
167
+ .filter((f) => f.endsWith(".md"))
168
+ .map((f) => f.replace(".md", ""));
160
169
  } catch {
161
170
  return [];
162
171
  }
@@ -164,8 +173,10 @@ class DependencyResolver {
164
173
 
165
174
  async listTeams() {
166
175
  try {
167
- const files = await fs.readdir(path.join(this.xiaomaCore, 'agent-teams'));
168
- return files.filter((f) => f.endsWith('.yaml')).map((f) => f.replace('.yaml', ''));
176
+ const files = await fs.readdir(path.join(this.xiaomaCore, "agent-teams"));
177
+ return files
178
+ .filter((f) => f.endsWith(".yaml"))
179
+ .map((f) => f.replace(".yaml", ""));
169
180
  } catch {
170
181
  return [];
171
182
  }
@@ -10,7 +10,9 @@
10
10
  */
11
11
  function extractYamlFromAgent(agentContent, cleanCommands = false) {
12
12
  // Remove carriage returns and match YAML block
13
- const yamlMatch = agentContent.replaceAll('\r', '').match(/```ya?ml\n([\s\S]*?)\n```/);
13
+ const yamlMatch = agentContent
14
+ .replaceAll("\r", "")
15
+ .match(/```ya?ml\n([\s\S]*?)\n```/);
14
16
  if (!yamlMatch) return null;
15
17
 
16
18
  let yamlContent = yamlMatch[1].trim();
@@ -18,7 +20,10 @@ function extractYamlFromAgent(agentContent, cleanCommands = false) {
18
20
  // Clean up command descriptions if requested
19
21
  // Converts "- command - description" to just "- command"
20
22
  if (cleanCommands) {
21
- yamlContent = yamlContent.replaceAll(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
23
+ yamlContent = yamlContent.replaceAll(
24
+ /^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm,
25
+ "$1$2",
26
+ );
22
27
  }
23
28
 
24
29
  return yamlContent;
@@ -1,16 +1,21 @@
1
- const { execSync } = require('node:child_process');
2
- const fs = require('node:fs');
1
+ const { execSync } = require("node:child_process");
2
+ const fs = require("node:fs");
3
3
 
4
4
  // Get the latest stable tag (exclude beta tags)
5
- const allTags = execSync('git tag -l | sort -V', { encoding: 'utf8' }).split('\n').filter(Boolean);
6
- const stableTags = allTags.filter((tag) => !tag.includes('beta'));
7
- const latestTag = stableTags.at(-1) || 'v5.0.0';
5
+ const allTags = execSync("git tag -l | sort -V", { encoding: "utf8" })
6
+ .split("\n")
7
+ .filter(Boolean);
8
+ const stableTags = allTags.filter((tag) => !tag.includes("beta"));
9
+ const latestTag = stableTags.at(-1) || "v5.0.0";
8
10
 
9
11
  // Get commits since last tag
10
- const commits = execSync(`git log ${latestTag}..HEAD --pretty=format:"- %s" --reverse`, {
11
- encoding: 'utf8',
12
- })
13
- .split('\n')
12
+ const commits = execSync(
13
+ `git log ${latestTag}..HEAD --pretty=format:"- %s" --reverse`,
14
+ {
15
+ encoding: "utf8",
16
+ },
17
+ )
18
+ .split("\n")
14
19
  .filter(Boolean);
15
20
 
16
21
  // Categorize commits
@@ -18,49 +23,52 @@ const features = commits.filter((commit) => /^- (feat|Feature)/.test(commit));
18
23
  const fixes = commits.filter((commit) => /^- (fix|Fix)/.test(commit));
19
24
  const chores = commits.filter((commit) => /^- (chore|Chore)/.test(commit));
20
25
  const others = commits.filter(
21
- (commit) => !/^- (feat|Feature|fix|Fix|chore|Chore|release:|Release:)/.test(commit),
26
+ (commit) =>
27
+ !/^- (feat|Feature|fix|Fix|chore|Chore|release:|Release:)/.test(commit),
22
28
  );
23
29
 
24
30
  // Get next version (you can modify this logic)
25
- const currentVersion = require('../package.json').version;
26
- const versionParts = currentVersion.split('.').map(Number);
31
+ const currentVersion = require("../package.json").version;
32
+ const versionParts = currentVersion.split(".").map(Number);
27
33
  const nextVersion = `${versionParts[0]}.${versionParts[1] + 1}.0`; // Default to minor bump
28
34
 
29
35
  console.log(`## πŸš€ What's New in v${nextVersion}\n`);
30
36
 
31
37
  if (features.length > 0) {
32
- console.log('### ✨ New Features');
38
+ console.log("### ✨ New Features");
33
39
  for (const feature of features) console.log(feature);
34
- console.log('');
40
+ console.log("");
35
41
  }
36
42
 
37
43
  if (fixes.length > 0) {
38
- console.log('### πŸ› Bug Fixes');
44
+ console.log("### πŸ› Bug Fixes");
39
45
  for (const fix of fixes) console.log(fix);
40
- console.log('');
46
+ console.log("");
41
47
  }
42
48
 
43
49
  if (others.length > 0) {
44
- console.log('### πŸ“¦ Other Changes');
50
+ console.log("### πŸ“¦ Other Changes");
45
51
  for (const other of others) console.log(other);
46
- console.log('');
52
+ console.log("");
47
53
  }
48
54
 
49
55
  if (chores.length > 0) {
50
- console.log('### πŸ”§ Maintenance');
56
+ console.log("### πŸ”§ Maintenance");
51
57
  for (const chore of chores) console.log(chore);
52
- console.log('');
58
+ console.log("");
53
59
  }
54
60
 
55
- console.log('\n## πŸ“¦ Installation\n');
56
- console.log('```bash');
57
- console.log('npx xiaoma-cli install');
58
- console.log('```');
61
+ console.log("\n## πŸ“¦ Installation\n");
62
+ console.log("```bash");
63
+ console.log("npx xiaoma-cli install");
64
+ console.log("```");
59
65
 
60
66
  console.log(
61
67
  `\n**Full Changelog**: https://github.com/zqyl-xiaoma/xiaoma-cli-release/compare/${latestTag}...v${nextVersion}`,
62
68
  );
63
69
 
64
- console.log(`\n---\nπŸ“Š **Summary**: ${commits.length} commits since ${latestTag}`);
70
+ console.log(
71
+ `\n---\nπŸ“Š **Summary**: ${commits.length} commits since ${latestTag}`,
72
+ );
65
73
  console.log(`🏷️ **Previous tag**: ${latestTag}`);
66
74
  console.log(`πŸš€ **Next version**: v${nextVersion} (estimated)`);
@@ -1,8 +1,8 @@
1
1
  // ASCII banner art definitions extracted from banners.js to separate art from logic
2
2
 
3
- const XIAOMA_TITLE = 'XIAOMA-CLIβ„’';
4
- const FLATTENER_TITLE = 'FLATTENER';
5
- const INSTALLER_TITLE = 'INSTALLER';
3
+ const XIAOMA_TITLE = "XIAOMA-CLIβ„’";
4
+ const FLATTENER_TITLE = "FLATTENER";
5
+ const INSTALLER_TITLE = "INSTALLER";
6
6
 
7
7
  // Large ASCII blocks (block-style fonts)
8
8
  const XIAOMA_LARGE = `
@@ -3,23 +3,32 @@
3
3
  * Used by semantic-release to keep versions in sync
4
4
  */
5
5
 
6
- const fs = require('node:fs');
7
- const path = require('node:path');
6
+ const fs = require("node:fs");
7
+ const path = require("node:path");
8
8
 
9
9
  function syncInstallerVersion() {
10
10
  // Read main package.json
11
- const mainPackagePath = path.join(__dirname, '..', 'package.json');
12
- const mainPackage = JSON.parse(fs.readFileSync(mainPackagePath, 'utf8'));
11
+ const mainPackagePath = path.join(__dirname, "..", "package.json");
12
+ const mainPackage = JSON.parse(fs.readFileSync(mainPackagePath, "utf8"));
13
13
 
14
14
  // Read installer package.json
15
- const installerPackagePath = path.join(__dirname, 'installer', 'package.json');
16
- const installerPackage = JSON.parse(fs.readFileSync(installerPackagePath, 'utf8'));
15
+ const installerPackagePath = path.join(
16
+ __dirname,
17
+ "installer",
18
+ "package.json",
19
+ );
20
+ const installerPackage = JSON.parse(
21
+ fs.readFileSync(installerPackagePath, "utf8"),
22
+ );
17
23
 
18
24
  // Update installer version to match main version
19
25
  installerPackage.version = mainPackage.version;
20
26
 
21
27
  // Write back installer package.json
22
- fs.writeFileSync(installerPackagePath, JSON.stringify(installerPackage, null, 2) + '\n');
28
+ fs.writeFileSync(
29
+ installerPackagePath,
30
+ JSON.stringify(installerPackage, null, 2) + "\n",
31
+ );
23
32
 
24
33
  console.log(`Synced installer version to ${mainPackage.version}`);
25
34
  }