mcp-probe-kit 1.11.0 → 1.15.0

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 (58) hide show
  1. package/README.md +215 -21
  2. package/build/index.js +21 -1
  3. package/build/schemas/index.d.ts +234 -0
  4. package/build/schemas/index.js +4 -0
  5. package/build/schemas/interview-tools.d.ts +72 -0
  6. package/build/schemas/interview-tools.js +64 -0
  7. package/build/schemas/orchestration-tools.d.ts +58 -0
  8. package/build/schemas/orchestration-tools.js +59 -0
  9. package/build/schemas/ui-ux-schemas.d.ts +248 -0
  10. package/build/schemas/ui-ux-schemas.js +147 -0
  11. package/build/tools/__tests__/start_ui.integration.test.d.ts +6 -0
  12. package/build/tools/__tests__/start_ui.integration.test.js +179 -0
  13. package/build/tools/__tests__/start_ui.property.test.d.ts +6 -0
  14. package/build/tools/__tests__/start_ui.property.test.js +263 -0
  15. package/build/tools/__tests__/start_ui.unit.test.d.ts +6 -0
  16. package/build/tools/__tests__/start_ui.unit.test.js +109 -0
  17. package/build/tools/ask_user.d.ts +17 -0
  18. package/build/tools/ask_user.js +124 -0
  19. package/build/tools/index.d.ts +7 -0
  20. package/build/tools/index.js +9 -0
  21. package/build/tools/init_component_catalog.d.ts +22 -0
  22. package/build/tools/init_component_catalog.js +809 -0
  23. package/build/tools/interview.d.ts +18 -0
  24. package/build/tools/interview.js +418 -0
  25. package/build/tools/render_ui.d.ts +22 -0
  26. package/build/tools/render_ui.js +384 -0
  27. package/build/tools/start_ralph.d.ts +16 -0
  28. package/build/tools/start_ralph.js +779 -0
  29. package/build/tools/start_ui.d.ts +25 -0
  30. package/build/tools/start_ui.js +299 -0
  31. package/build/tools/ui-ux-tools.d.ts +116 -0
  32. package/build/tools/ui-ux-tools.js +756 -0
  33. package/build/tools/ui-ux-tools.test.d.ts +6 -0
  34. package/build/tools/ui-ux-tools.test.js +132 -0
  35. package/build/utils/ascii-box-formatter.d.ts +29 -0
  36. package/build/utils/ascii-box-formatter.js +195 -0
  37. package/build/utils/bm25.d.ts +60 -0
  38. package/build/utils/bm25.js +139 -0
  39. package/build/utils/cache-manager.d.ts +65 -0
  40. package/build/utils/cache-manager.js +156 -0
  41. package/build/utils/design-docs-generator.d.ts +1 -0
  42. package/build/utils/design-docs-generator.js +1 -0
  43. package/build/utils/design-reasoning-engine.d.ts +158 -0
  44. package/build/utils/design-reasoning-engine.js +363 -0
  45. package/build/utils/design-system-json-formatter.d.ts +41 -0
  46. package/build/utils/design-system-json-formatter.js +165 -0
  47. package/build/utils/ui-data-loader.d.ts +56 -0
  48. package/build/utils/ui-data-loader.js +164 -0
  49. package/build/utils/ui-search-engine.d.ts +57 -0
  50. package/build/utils/ui-search-engine.js +123 -0
  51. package/build/utils/ui-sync.d.ts +13 -0
  52. package/build/utils/ui-sync.js +241 -0
  53. package/docs/BEST_PRACTICES.md +456 -6
  54. package/docs/HOW_TO_TRIGGER.md +195 -64
  55. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.html +158 -63
  56. package/docs/MCP-Probe-Kit-/344/275/277/347/224/250/346/211/213/345/206/214.md +872 -34
  57. package/package.json +18 -5
  58. package/docs/HOW_TO_TRIGGER.html +0 -243
@@ -0,0 +1,241 @@
1
+ /**
2
+ * UI/UX 数据同步工具
3
+ *
4
+ * 从 npm 包 uipro-cli 同步数据到缓存目录
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import * as os from 'os';
9
+ import * as https from 'https';
10
+ import * as tar from 'tar';
11
+ import { createWriteStream } from 'fs';
12
+ import { parse as parseCSV } from 'csv-parse/sync';
13
+ /**
14
+ * 获取 npm 包的最新版本号
15
+ */
16
+ async function getLatestVersion(packageName) {
17
+ return new Promise((resolve, reject) => {
18
+ const url = `https://registry.npmjs.org/${packageName}/latest`;
19
+ https.get(url, (res) => {
20
+ let data = '';
21
+ res.on('data', (chunk) => {
22
+ data += chunk;
23
+ });
24
+ res.on('end', () => {
25
+ try {
26
+ const pkg = JSON.parse(data);
27
+ resolve(pkg.version);
28
+ }
29
+ catch (error) {
30
+ reject(new Error(`Failed to parse package metadata: ${error}`));
31
+ }
32
+ });
33
+ }).on('error', (error) => {
34
+ reject(new Error(`Failed to fetch package metadata: ${error}`));
35
+ });
36
+ });
37
+ }
38
+ /**
39
+ * 下载文件
40
+ */
41
+ async function downloadFile(url, outputPath) {
42
+ return new Promise((resolve, reject) => {
43
+ https.get(url, (res) => {
44
+ if (res.statusCode === 302 || res.statusCode === 301) {
45
+ if (res.headers.location) {
46
+ downloadFile(res.headers.location, outputPath).then(resolve).catch(reject);
47
+ return;
48
+ }
49
+ }
50
+ if (res.statusCode !== 200) {
51
+ reject(new Error(`Failed to download: HTTP ${res.statusCode}`));
52
+ return;
53
+ }
54
+ const fileStream = createWriteStream(outputPath);
55
+ res.pipe(fileStream);
56
+ fileStream.on('finish', () => {
57
+ fileStream.close();
58
+ resolve();
59
+ });
60
+ fileStream.on('error', (error) => {
61
+ fs.unlinkSync(outputPath);
62
+ reject(error);
63
+ });
64
+ }).on('error', (error) => {
65
+ reject(error);
66
+ });
67
+ });
68
+ }
69
+ /**
70
+ * 解压 tarball 并提取指定目录
71
+ */
72
+ async function extractTarball(tarballPath, extractPath, targetDir) {
73
+ const tempDir = path.join(extractPath, '.temp');
74
+ if (!fs.existsSync(tempDir)) {
75
+ fs.mkdirSync(tempDir, { recursive: true });
76
+ }
77
+ await tar.extract({
78
+ file: tarballPath,
79
+ cwd: tempDir,
80
+ });
81
+ const sourceDir = path.join(tempDir, targetDir);
82
+ if (!fs.existsSync(sourceDir)) {
83
+ throw new Error(`Target directory not found in tarball: ${targetDir}`);
84
+ }
85
+ return sourceDir;
86
+ }
87
+ /**
88
+ * 转换 CSV 到 JSON
89
+ */
90
+ function convertCSVToJSON(csvContent, filename) {
91
+ try {
92
+ const records = parseCSV(csvContent, {
93
+ columns: true,
94
+ skip_empty_lines: true,
95
+ trim: true,
96
+ relax_quotes: true,
97
+ relax_column_count: true,
98
+ escape: '\\',
99
+ quote: '"',
100
+ skip_records_with_error: true,
101
+ });
102
+ return records;
103
+ }
104
+ catch (error) {
105
+ console.warn(`Warning: Failed to parse ${filename}, skipping: ${error}`);
106
+ return [];
107
+ }
108
+ }
109
+ /**
110
+ * 处理数据文件
111
+ */
112
+ async function processDataFiles(sourceDir, outputDir, verbose) {
113
+ if (!fs.existsSync(outputDir)) {
114
+ fs.mkdirSync(outputDir, { recursive: true });
115
+ }
116
+ const files = fs.readdirSync(sourceDir);
117
+ for (const file of files) {
118
+ const sourcePath = path.join(sourceDir, file);
119
+ const stat = fs.statSync(sourcePath);
120
+ if (stat.isDirectory()) {
121
+ const subOutputDir = path.join(outputDir, file);
122
+ await processDataFiles(sourcePath, subOutputDir, verbose);
123
+ continue;
124
+ }
125
+ if (!file.endsWith('.csv')) {
126
+ continue;
127
+ }
128
+ if (verbose) {
129
+ console.log(`Processing: ${file}`);
130
+ }
131
+ const csvContent = fs.readFileSync(sourcePath, 'utf-8');
132
+ const jsonData = convertCSVToJSON(csvContent, file);
133
+ if (jsonData.length === 0) {
134
+ if (verbose) {
135
+ console.log(` ⚠️ Skipped ${file} (no valid records)`);
136
+ }
137
+ continue;
138
+ }
139
+ const outputFile = file.replace('.csv', '.json');
140
+ const outputPath = path.join(outputDir, outputFile);
141
+ fs.writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), 'utf-8');
142
+ if (verbose) {
143
+ console.log(` → ${outputFile} (${jsonData.length} records)`);
144
+ }
145
+ }
146
+ }
147
+ /**
148
+ * 写入元数据
149
+ */
150
+ function writeMetadata(outputDir, metadata) {
151
+ const metadataPath = path.join(outputDir, 'metadata.json');
152
+ fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8');
153
+ }
154
+ /**
155
+ * 清理临时文件
156
+ */
157
+ function cleanup(tempDir) {
158
+ if (fs.existsSync(tempDir)) {
159
+ fs.rmSync(tempDir, { recursive: true, force: true });
160
+ }
161
+ }
162
+ /**
163
+ * 同步 UI/UX 数据到指定目录(通用函数)
164
+ */
165
+ export async function syncUIDataTo(outputDir, verbose = false) {
166
+ const packageName = 'uipro-cli';
167
+ if (verbose) {
168
+ console.log('🚀 Starting UI/UX data sync...\n');
169
+ }
170
+ try {
171
+ // 1. 获取最新版本
172
+ if (verbose) {
173
+ console.log(`Fetching latest version of ${packageName}...`);
174
+ }
175
+ const latestVersion = await getLatestVersion(packageName);
176
+ if (verbose) {
177
+ console.log(`✓ Latest version: ${latestVersion}\n`);
178
+ }
179
+ // 2. 下载 tarball
180
+ const tarballUrl = `https://registry.npmjs.org/${packageName}/-/${packageName}-${latestVersion}.tgz`;
181
+ const tempDir = path.join(os.tmpdir(), '.mcp-ui-sync');
182
+ const tarballPath = path.join(tempDir, 'package.tgz');
183
+ if (!fs.existsSync(tempDir)) {
184
+ fs.mkdirSync(tempDir, { recursive: true });
185
+ }
186
+ if (verbose) {
187
+ console.log(`Downloading tarball...`);
188
+ }
189
+ await downloadFile(tarballUrl, tarballPath);
190
+ if (verbose) {
191
+ console.log('✓ Downloaded tarball\n');
192
+ }
193
+ // 3. 解压并提取数据
194
+ if (verbose) {
195
+ console.log('Extracting data files...');
196
+ }
197
+ const extractedDataDir = await extractTarball(tarballPath, tempDir, 'package/assets/data');
198
+ if (verbose) {
199
+ console.log('✓ Extracted data files\n');
200
+ }
201
+ // 4. 处理数据文件
202
+ if (verbose) {
203
+ console.log('Processing data files...');
204
+ }
205
+ await processDataFiles(extractedDataDir, outputDir, verbose);
206
+ if (verbose) {
207
+ console.log('✓ Processed all data files\n');
208
+ }
209
+ // 5. 写入元数据
210
+ const metadata = {
211
+ version: latestVersion,
212
+ syncedAt: new Date().toISOString(),
213
+ source: packageName,
214
+ format: 'json',
215
+ };
216
+ writeMetadata(outputDir, metadata);
217
+ if (verbose) {
218
+ console.log('✓ Written metadata\n');
219
+ }
220
+ // 6. 清理临时文件
221
+ cleanup(tempDir);
222
+ if (verbose) {
223
+ console.log('✓ Cleaned up temporary files\n');
224
+ console.log('✅ Sync completed successfully!');
225
+ console.log(` Version: ${latestVersion}`);
226
+ console.log(` Output: ${outputDir}`);
227
+ }
228
+ }
229
+ catch (error) {
230
+ const tempDir = path.join(os.tmpdir(), '.mcp-ui-sync');
231
+ cleanup(tempDir);
232
+ throw error;
233
+ }
234
+ }
235
+ /**
236
+ * 同步 UI/UX 数据到缓存
237
+ */
238
+ export async function syncUIDataToCache(force = false, verbose = false) {
239
+ const cacheDir = path.join(os.homedir(), '.mcp-probe-kit', 'ui-ux-data');
240
+ await syncUIDataTo(cacheDir, verbose);
241
+ }