uloop-cli 0.50.2 → 0.52.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.
- package/dist/cli.bundle.cjs +2460 -201
- package/dist/cli.bundle.cjs.map +3 -3
- package/package.json +1 -1
- package/scripts/generate-bundled-skills.ts +53 -10
- package/src/default-tools.json +13 -3
- package/src/skills/bundled-skills.ts +2220 -4
- package/src/skills/skills-manager.ts +49 -7
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* 2. skill-definitions/cli-only/SKILL.md (CLI-only skills)
|
|
6
|
-
*
|
|
7
|
-
* Skills with `internal: true` in frontmatter are excluded from generation.
|
|
8
|
-
*
|
|
9
|
-
* Usage: npx tsx scripts/generate-bundled-skills.ts
|
|
2
|
+
* Skills are scattered across multiple directories (McpTools, cli-only).
|
|
3
|
+
* Without this generator, we'd need manual synchronization between source
|
|
4
|
+
* SKILL.md files and the bundled output, which is error-prone and tedious.
|
|
10
5
|
*/
|
|
11
6
|
|
|
12
7
|
import { readdirSync, readFileSync, writeFileSync, existsSync } from 'fs';
|
|
@@ -26,6 +21,7 @@ interface SkillMetadata {
|
|
|
26
21
|
name: string;
|
|
27
22
|
isInternal: boolean;
|
|
28
23
|
importPath: string;
|
|
24
|
+
skillDirPath: string;
|
|
29
25
|
}
|
|
30
26
|
|
|
31
27
|
function parseFrontmatter(content: string): Record<string, string | boolean> {
|
|
@@ -75,8 +71,29 @@ function getSkillMetadataFromPath(
|
|
|
75
71
|
|
|
76
72
|
const relativePath = relative(OUTPUT_DIR, skillMdPath).replace(/\\/g, '/');
|
|
77
73
|
const importPath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
|
74
|
+
const skillDirPath = dirname(skillMdPath);
|
|
75
|
+
|
|
76
|
+
return { dirName, name, isInternal, importPath, skillDirPath };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function collectAdditionalFiles(skillDirPath: string): Record<string, string> {
|
|
80
|
+
const examplesDir = join(skillDirPath, 'examples');
|
|
81
|
+
if (!existsSync(examplesDir)) {
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
78
84
|
|
|
79
|
-
|
|
85
|
+
const files: Record<string, string> = {};
|
|
86
|
+
const entries = readdirSync(examplesDir, { withFileTypes: true });
|
|
87
|
+
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
90
|
+
const filePath = join(examplesDir, entry.name);
|
|
91
|
+
const relativePath = `examples/${entry.name}`;
|
|
92
|
+
files[relativePath] = readFileSync(filePath, 'utf-8');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return files;
|
|
80
97
|
}
|
|
81
98
|
|
|
82
99
|
function collectSkillsFromMcpTools(): SkillMetadata[] {
|
|
@@ -134,6 +151,13 @@ function toVariableName(dirName: string): string {
|
|
|
134
151
|
.concat('Skill');
|
|
135
152
|
}
|
|
136
153
|
|
|
154
|
+
function escapeStringForTemplate(str: string): string {
|
|
155
|
+
return str
|
|
156
|
+
.replace(/\\/g, '\\\\')
|
|
157
|
+
.replace(/`/g, '\\`')
|
|
158
|
+
.replace(/\$\{/g, '\\${');
|
|
159
|
+
}
|
|
160
|
+
|
|
137
161
|
function generateBundledSkillsFile(skills: SkillMetadata[]): string {
|
|
138
162
|
const imports = skills
|
|
139
163
|
.map((skill) => {
|
|
@@ -145,10 +169,27 @@ function generateBundledSkillsFile(skills: SkillMetadata[]): string {
|
|
|
145
169
|
const entries = skills
|
|
146
170
|
.map((skill) => {
|
|
147
171
|
const varName = toVariableName(skill.dirName);
|
|
172
|
+
const additionalFiles = collectAdditionalFiles(skill.skillDirPath);
|
|
173
|
+
const hasAdditionalFiles = Object.keys(additionalFiles).length > 0;
|
|
174
|
+
|
|
175
|
+
let additionalFilesCode = '';
|
|
176
|
+
if (hasAdditionalFiles) {
|
|
177
|
+
const fileEntries = Object.entries(additionalFiles)
|
|
178
|
+
.map(([path, content]) => {
|
|
179
|
+
const escapedContent = escapeStringForTemplate(content);
|
|
180
|
+
return ` '${path}': \`${escapedContent}\`,`;
|
|
181
|
+
})
|
|
182
|
+
.join('\n');
|
|
183
|
+
additionalFilesCode = `
|
|
184
|
+
additionalFiles: {
|
|
185
|
+
${fileEntries}
|
|
186
|
+
},`;
|
|
187
|
+
}
|
|
188
|
+
|
|
148
189
|
return ` {
|
|
149
190
|
name: '${skill.name}',
|
|
150
191
|
dirName: '${skill.dirName}',
|
|
151
|
-
content: ${varName}
|
|
192
|
+
content: ${varName},${additionalFilesCode}
|
|
152
193
|
},`;
|
|
153
194
|
})
|
|
154
195
|
.join('\n');
|
|
@@ -159,6 +200,7 @@ function generateBundledSkillsFile(skills: SkillMetadata[]): string {
|
|
|
159
200
|
*
|
|
160
201
|
* This file is automatically generated from:
|
|
161
202
|
* - Editor/Api/McpTools/<ToolFolder>/SKILL.md
|
|
203
|
+
* - Editor/Api/McpTools/<ToolFolder>/examples/*.md (additional files)
|
|
162
204
|
* - skill-definitions/cli-only/<SkillFolder>/SKILL.md
|
|
163
205
|
*
|
|
164
206
|
* To add a new skill, create a SKILL.md file in the appropriate location.
|
|
@@ -171,6 +213,7 @@ export interface BundledSkill {
|
|
|
171
213
|
name: string;
|
|
172
214
|
dirName: string;
|
|
173
215
|
content: string;
|
|
216
|
+
additionalFiles?: Record<string, string>;
|
|
174
217
|
}
|
|
175
218
|
|
|
176
219
|
export const BUNDLED_SKILLS: BundledSkill[] = [
|
package/src/default-tools.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.52.0",
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "compile",
|
|
@@ -274,8 +274,8 @@
|
|
|
274
274
|
}
|
|
275
275
|
},
|
|
276
276
|
{
|
|
277
|
-
"name": "capture-
|
|
278
|
-
"description": "Capture Unity EditorWindow and save as PNG
|
|
277
|
+
"name": "capture-window",
|
|
278
|
+
"description": "Capture Unity EditorWindow and save as PNG",
|
|
279
279
|
"inputSchema": {
|
|
280
280
|
"type": "object",
|
|
281
281
|
"properties": {
|
|
@@ -288,6 +288,16 @@
|
|
|
288
288
|
"type": "number",
|
|
289
289
|
"description": "Resolution scale (0.1 to 1.0)",
|
|
290
290
|
"default": 1
|
|
291
|
+
},
|
|
292
|
+
"MatchMode": {
|
|
293
|
+
"type": "string",
|
|
294
|
+
"description": "Window name matching mode (all case-insensitive)",
|
|
295
|
+
"enum": [
|
|
296
|
+
"exact",
|
|
297
|
+
"prefix",
|
|
298
|
+
"contains"
|
|
299
|
+
],
|
|
300
|
+
"default": "exact"
|
|
291
301
|
}
|
|
292
302
|
}
|
|
293
303
|
}
|