@unityclaw/skills 1.0.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/README.md +125 -0
- package/dist/chunk-KHQZYC3Y.js +163 -0
- package/dist/cli.cjs +237 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +69 -0
- package/dist/index.cjs +197 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +18 -0
- package/package.json +59 -0
- package/unityclaw-document-convert/SKILL.md +375 -0
- package/unityclaw-document-translation/SKILL.md +273 -0
- package/unityclaw-image-compress/SKILL.md +229 -0
- package/unityclaw-image-generation/SKILL.md +213 -0
- package/unityclaw-media-analysis/SKILL.md +315 -0
- package/unityclaw-video-generation-kling/SKILL.md +233 -0
- package/unityclaw-video-generation-other/SKILL.md +284 -0
- package/unityclaw-video-generation-sora/SKILL.md +250 -0
- package/unityclaw-video-generation-veo/SKILL.md +239 -0
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# @unityclaw/skills
|
|
2
|
+
|
|
3
|
+
UnityClaw Skills - Claude Code and OpenClaw skill definitions for AI-powered image/video generation, media analysis, and document processing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install globally for CLI usage
|
|
9
|
+
npm install -g @unityclaw/skills
|
|
10
|
+
|
|
11
|
+
# Or use with npx (no installation required)
|
|
12
|
+
npx @unityclaw/skills --help
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
All skills require the `@unityclaw/sdk` package and an API key:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
export UNITYCLAW_API_KEY=your-api-key
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## CLI Commands
|
|
22
|
+
|
|
23
|
+
### Install Skills
|
|
24
|
+
|
|
25
|
+
Install skills to Claude Code or OpenClaw:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Install all skills to Claude Code
|
|
29
|
+
npx @unityclaw/skills install
|
|
30
|
+
|
|
31
|
+
# Install specific skills
|
|
32
|
+
npx @unityclaw/skills install unityclaw-image-generation unityclaw-video-generation-sora
|
|
33
|
+
|
|
34
|
+
# Install to OpenClaw
|
|
35
|
+
npx @unityclaw/skills install --target openclaw
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### List Available Skills
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx @unityclaw/skills list
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Update Packages
|
|
45
|
+
|
|
46
|
+
Update SDK and skills to the latest version:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Update local packages
|
|
50
|
+
npx @unityclaw/skills update
|
|
51
|
+
|
|
52
|
+
# Update global packages
|
|
53
|
+
npx @unityclaw/skills update --global
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Execute Skills Directly
|
|
57
|
+
|
|
58
|
+
Execute a skill via Claude Code CLI:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Generate an image
|
|
62
|
+
npx @unityclaw/skills /unityclaw-image-generation 我要一张竖屏的桌面背景图
|
|
63
|
+
|
|
64
|
+
# Analyze a video
|
|
65
|
+
npx @unityclaw/skills /unityclaw-media-analysis https://youtube.com/watch?v=...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Available Skills
|
|
69
|
+
|
|
70
|
+
### Image Skills
|
|
71
|
+
|
|
72
|
+
| Skill | Description | Emoji |
|
|
73
|
+
|-------|-------------|-------|
|
|
74
|
+
| [unityclaw-image-generation](./unityclaw-image-generation/SKILL.md) | Generate images using Gemini or JiMeng models | 🎨 |
|
|
75
|
+
| [unityclaw-image-compress](./unityclaw-image-compress/SKILL.md) | Compress images with quality control | 🗜️ |
|
|
76
|
+
|
|
77
|
+
### Video Skills
|
|
78
|
+
|
|
79
|
+
| Skill | Description | Emoji |
|
|
80
|
+
|-------|-------------|-------|
|
|
81
|
+
| [unityclaw-video-generation-sora](./unityclaw-video-generation-sora/SKILL.md) | Generate videos using OpenAI Sora | 🎬 |
|
|
82
|
+
| [unityclaw-video-generation-veo](./unityclaw-video-generation-veo/SKILL.md) | Generate videos using Google Veo | 🎥 |
|
|
83
|
+
| [unityclaw-video-generation-kling](./unityclaw-video-generation-kling/SKILL.md) | Generate videos using Kling AI | 📹 |
|
|
84
|
+
| [unityclaw-video-generation-other](./unityclaw-video-generation-other/SKILL.md) | Generate videos using Doubao, Wan, MiniMax, JiMeng | 🎞️ |
|
|
85
|
+
|
|
86
|
+
### Document Skills
|
|
87
|
+
|
|
88
|
+
| Skill | Description | Emoji |
|
|
89
|
+
|-------|-------------|-------|
|
|
90
|
+
| [unityclaw-document-translation](./unityclaw-document-translation/SKILL.md) | Translate documents between languages | 🌐 |
|
|
91
|
+
| [unityclaw-document-convert](./unityclaw-document-convert/SKILL.md) | Convert document formats (PDF/Word/PPT/Excel/Image) | 📄 |
|
|
92
|
+
|
|
93
|
+
### Media Skills
|
|
94
|
+
|
|
95
|
+
| Skill | Description | Emoji |
|
|
96
|
+
|-------|-------------|-------|
|
|
97
|
+
| [unityclaw-media-analysis](./unityclaw-media-analysis/SKILL.md) | Analyze video/audio content and extract insights | 📊 |
|
|
98
|
+
|
|
99
|
+
## Programmatic Usage
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { listSkills, installSkills, executeSkill } from '@unityclaw/skills';
|
|
103
|
+
|
|
104
|
+
// List available skills
|
|
105
|
+
const skills = await listSkills();
|
|
106
|
+
console.log(skills);
|
|
107
|
+
|
|
108
|
+
// Install skills to Claude Code
|
|
109
|
+
await installSkills('claude', ['unityclaw-image-generation']);
|
|
110
|
+
|
|
111
|
+
// Install all skills to OpenClaw
|
|
112
|
+
await installSkills('openclaw');
|
|
113
|
+
|
|
114
|
+
// Execute a skill
|
|
115
|
+
await executeSkill('/unityclaw-image-generation A beautiful sunset');
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## SDK Documentation
|
|
119
|
+
|
|
120
|
+
- [npm: @unityclaw/sdk](https://www.npmjs.com/package/@unityclaw/sdk)
|
|
121
|
+
- [UnityClaw Homepage](https://unityclaw.com)
|
|
122
|
+
|
|
123
|
+
## License
|
|
124
|
+
|
|
125
|
+
MIT
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
import { spawn } from "child_process";
|
|
10
|
+
import { cp, mkdir, readdir, readFile } from "fs/promises";
|
|
11
|
+
import { existsSync, readdirSync } from "fs";
|
|
12
|
+
import path from "path";
|
|
13
|
+
function getSkillsDir() {
|
|
14
|
+
let currentDir;
|
|
15
|
+
try {
|
|
16
|
+
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
17
|
+
const { fileURLToPath } = __require("url");
|
|
18
|
+
currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
} else if (typeof __dirname !== "undefined") {
|
|
20
|
+
currentDir = __dirname;
|
|
21
|
+
} else {
|
|
22
|
+
currentDir = process.cwd();
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
currentDir = process.cwd();
|
|
26
|
+
}
|
|
27
|
+
let searchDir = currentDir;
|
|
28
|
+
const root = path.parse(searchDir).root;
|
|
29
|
+
while (searchDir !== root) {
|
|
30
|
+
try {
|
|
31
|
+
const entries = readdirSync(searchDir);
|
|
32
|
+
const hasSkills = entries.some((e) => /^unityclaw-/.test(e) || /^unityclaw-/.test(e));
|
|
33
|
+
if (hasSkills) {
|
|
34
|
+
return searchDir;
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
searchDir = path.dirname(searchDir);
|
|
39
|
+
}
|
|
40
|
+
return path.dirname(currentDir);
|
|
41
|
+
}
|
|
42
|
+
async function parseSkill(skillPath) {
|
|
43
|
+
try {
|
|
44
|
+
const content = await readFile(skillPath, "utf-8");
|
|
45
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
46
|
+
if (!frontmatterMatch) return null;
|
|
47
|
+
const frontmatter = frontmatterMatch[1];
|
|
48
|
+
const meta = {};
|
|
49
|
+
for (const line of frontmatter.split("\n")) {
|
|
50
|
+
const match = line.match(/^(\w+(?:\.\w+)*):\s*(.+)$/);
|
|
51
|
+
if (match) {
|
|
52
|
+
const [, key, value] = match;
|
|
53
|
+
if (key.includes(".")) {
|
|
54
|
+
const parts = key.split(".");
|
|
55
|
+
let current = meta;
|
|
56
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
57
|
+
if (!current[parts[i]]) current[parts[i]] = {};
|
|
58
|
+
current = current[parts[i]];
|
|
59
|
+
}
|
|
60
|
+
current[parts[parts.length - 1]] = value.replace(/^["']|["']$/g, "");
|
|
61
|
+
} else {
|
|
62
|
+
meta[key] = value.replace(/^["']|["']$/g, "");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return meta;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function listSkills() {
|
|
72
|
+
const skillsDir = getSkillsDir();
|
|
73
|
+
const skills = [];
|
|
74
|
+
try {
|
|
75
|
+
const entries = await readdir(skillsDir, { withFileTypes: true });
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (!entry.isDirectory()) continue;
|
|
78
|
+
if (!entry.name.startsWith("unityclaw-") && !entry.name.startsWith("unityclaw-")) continue;
|
|
79
|
+
if (entry.name === "src" || entry.name === "dist" || entry.name === "node_modules") continue;
|
|
80
|
+
const skillFile = path.join(skillsDir, entry.name, "SKILL.md");
|
|
81
|
+
if (existsSync(skillFile)) {
|
|
82
|
+
const meta = await parseSkill(skillFile);
|
|
83
|
+
skills.push({
|
|
84
|
+
name: entry.name,
|
|
85
|
+
path: skillFile,
|
|
86
|
+
meta
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error("Error listing skills:", error);
|
|
92
|
+
}
|
|
93
|
+
return skills;
|
|
94
|
+
}
|
|
95
|
+
function getClaudeSkillsDir() {
|
|
96
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
97
|
+
return path.join(homeDir, ".claude", "skills");
|
|
98
|
+
}
|
|
99
|
+
function getOpenClawSkillsDir() {
|
|
100
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
101
|
+
return process.env.OPENCLAW_SKILLS_DIR || path.join(homeDir, ".openclaw", "skills");
|
|
102
|
+
}
|
|
103
|
+
async function installSkills(target, skills) {
|
|
104
|
+
const targetDir = target === "claude" ? getClaudeSkillsDir() : getOpenClawSkillsDir();
|
|
105
|
+
const skillsDir = getSkillsDir();
|
|
106
|
+
console.log(`Installing skills to ${target}...`);
|
|
107
|
+
console.log(`Target directory: ${targetDir}`);
|
|
108
|
+
if (!existsSync(targetDir)) {
|
|
109
|
+
await mkdir(targetDir, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
const availableSkills = await listSkills();
|
|
112
|
+
const skillsToInstall = skills && skills.length > 0 ? availableSkills.filter((s) => skills.includes(s.name)) : availableSkills;
|
|
113
|
+
if (skillsToInstall.length === 0) {
|
|
114
|
+
console.log("No skills to install.");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
console.log(`
|
|
118
|
+
Installing ${skillsToInstall.length} skill(s):
|
|
119
|
+
`);
|
|
120
|
+
for (const skill of skillsToInstall) {
|
|
121
|
+
const srcDir = path.join(skillsDir, skill.name);
|
|
122
|
+
const destDir = path.join(targetDir, skill.name);
|
|
123
|
+
try {
|
|
124
|
+
await cp(srcDir, destDir, { recursive: true });
|
|
125
|
+
console.log(` \u2705 ${skill.name}${skill.meta ? ` - ${skill.meta.description}` : ""}`);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.log(` \u274C ${skill.name} - Error: ${error}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
console.log(`
|
|
131
|
+
\u2728 Done! Skills installed to: ${targetDir}`);
|
|
132
|
+
}
|
|
133
|
+
async function executeSkill(skillCommand) {
|
|
134
|
+
const fullCommand = `claude "${skillCommand}"`;
|
|
135
|
+
console.log(`Executing: ${fullCommand}
|
|
136
|
+
`);
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const child = spawn("claude", [skillCommand], {
|
|
139
|
+
stdio: "inherit",
|
|
140
|
+
shell: true
|
|
141
|
+
});
|
|
142
|
+
child.on("close", (code) => {
|
|
143
|
+
if (code === 0) {
|
|
144
|
+
resolve();
|
|
145
|
+
} else {
|
|
146
|
+
reject(new Error(`Command failed with code ${code}`));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
child.on("error", (error) => {
|
|
150
|
+
reject(error);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
getSkillsDir,
|
|
157
|
+
parseSkill,
|
|
158
|
+
listSkills,
|
|
159
|
+
getClaudeSkillsDir,
|
|
160
|
+
getOpenClawSkillsDir,
|
|
161
|
+
installSkills,
|
|
162
|
+
executeSkill
|
|
163
|
+
};
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/cli.ts
|
|
27
|
+
var import_commander = require("commander");
|
|
28
|
+
var import_child_process2 = require("child_process");
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var import_child_process = require("child_process");
|
|
32
|
+
var import_promises = require("fs/promises");
|
|
33
|
+
var import_fs = require("fs");
|
|
34
|
+
var import_path = __toESM(require("path"), 1);
|
|
35
|
+
var import_meta = {};
|
|
36
|
+
function getSkillsDir() {
|
|
37
|
+
let currentDir;
|
|
38
|
+
try {
|
|
39
|
+
if (typeof import_meta !== "undefined" && import_meta.url) {
|
|
40
|
+
const { fileURLToPath } = require("url");
|
|
41
|
+
currentDir = import_path.default.dirname(fileURLToPath(import_meta.url));
|
|
42
|
+
} else if (typeof __dirname !== "undefined") {
|
|
43
|
+
currentDir = __dirname;
|
|
44
|
+
} else {
|
|
45
|
+
currentDir = process.cwd();
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
currentDir = process.cwd();
|
|
49
|
+
}
|
|
50
|
+
let searchDir = currentDir;
|
|
51
|
+
const root = import_path.default.parse(searchDir).root;
|
|
52
|
+
while (searchDir !== root) {
|
|
53
|
+
try {
|
|
54
|
+
const entries = (0, import_fs.readdirSync)(searchDir);
|
|
55
|
+
const hasSkills = entries.some((e) => /^unityclaw-/.test(e) || /^unityclaw-/.test(e));
|
|
56
|
+
if (hasSkills) {
|
|
57
|
+
return searchDir;
|
|
58
|
+
}
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
searchDir = import_path.default.dirname(searchDir);
|
|
62
|
+
}
|
|
63
|
+
return import_path.default.dirname(currentDir);
|
|
64
|
+
}
|
|
65
|
+
async function parseSkill(skillPath) {
|
|
66
|
+
try {
|
|
67
|
+
const content = await (0, import_promises.readFile)(skillPath, "utf-8");
|
|
68
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
69
|
+
if (!frontmatterMatch) return null;
|
|
70
|
+
const frontmatter = frontmatterMatch[1];
|
|
71
|
+
const meta = {};
|
|
72
|
+
for (const line of frontmatter.split("\n")) {
|
|
73
|
+
const match = line.match(/^(\w+(?:\.\w+)*):\s*(.+)$/);
|
|
74
|
+
if (match) {
|
|
75
|
+
const [, key, value] = match;
|
|
76
|
+
if (key.includes(".")) {
|
|
77
|
+
const parts = key.split(".");
|
|
78
|
+
let current = meta;
|
|
79
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
80
|
+
if (!current[parts[i]]) current[parts[i]] = {};
|
|
81
|
+
current = current[parts[i]];
|
|
82
|
+
}
|
|
83
|
+
current[parts[parts.length - 1]] = value.replace(/^["']|["']$/g, "");
|
|
84
|
+
} else {
|
|
85
|
+
meta[key] = value.replace(/^["']|["']$/g, "");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return meta;
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function listSkills() {
|
|
95
|
+
const skillsDir = getSkillsDir();
|
|
96
|
+
const skills = [];
|
|
97
|
+
try {
|
|
98
|
+
const entries = await (0, import_promises.readdir)(skillsDir, { withFileTypes: true });
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
if (!entry.isDirectory()) continue;
|
|
101
|
+
if (!entry.name.startsWith("unityclaw-") && !entry.name.startsWith("unityclaw-")) continue;
|
|
102
|
+
if (entry.name === "src" || entry.name === "dist" || entry.name === "node_modules") continue;
|
|
103
|
+
const skillFile = import_path.default.join(skillsDir, entry.name, "SKILL.md");
|
|
104
|
+
if ((0, import_fs.existsSync)(skillFile)) {
|
|
105
|
+
const meta = await parseSkill(skillFile);
|
|
106
|
+
skills.push({
|
|
107
|
+
name: entry.name,
|
|
108
|
+
path: skillFile,
|
|
109
|
+
meta
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error("Error listing skills:", error);
|
|
115
|
+
}
|
|
116
|
+
return skills;
|
|
117
|
+
}
|
|
118
|
+
function getClaudeSkillsDir() {
|
|
119
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
120
|
+
return import_path.default.join(homeDir, ".claude", "skills");
|
|
121
|
+
}
|
|
122
|
+
function getOpenClawSkillsDir() {
|
|
123
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
124
|
+
return process.env.OPENCLAW_SKILLS_DIR || import_path.default.join(homeDir, ".openclaw", "skills");
|
|
125
|
+
}
|
|
126
|
+
async function installSkills(target, skills) {
|
|
127
|
+
const targetDir = target === "claude" ? getClaudeSkillsDir() : getOpenClawSkillsDir();
|
|
128
|
+
const skillsDir = getSkillsDir();
|
|
129
|
+
console.log(`Installing skills to ${target}...`);
|
|
130
|
+
console.log(`Target directory: ${targetDir}`);
|
|
131
|
+
if (!(0, import_fs.existsSync)(targetDir)) {
|
|
132
|
+
await (0, import_promises.mkdir)(targetDir, { recursive: true });
|
|
133
|
+
}
|
|
134
|
+
const availableSkills = await listSkills();
|
|
135
|
+
const skillsToInstall = skills && skills.length > 0 ? availableSkills.filter((s) => skills.includes(s.name)) : availableSkills;
|
|
136
|
+
if (skillsToInstall.length === 0) {
|
|
137
|
+
console.log("No skills to install.");
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
console.log(`
|
|
141
|
+
Installing ${skillsToInstall.length} skill(s):
|
|
142
|
+
`);
|
|
143
|
+
for (const skill of skillsToInstall) {
|
|
144
|
+
const srcDir = import_path.default.join(skillsDir, skill.name);
|
|
145
|
+
const destDir = import_path.default.join(targetDir, skill.name);
|
|
146
|
+
try {
|
|
147
|
+
await (0, import_promises.cp)(srcDir, destDir, { recursive: true });
|
|
148
|
+
console.log(` \u2705 ${skill.name}${skill.meta ? ` - ${skill.meta.description}` : ""}`);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.log(` \u274C ${skill.name} - Error: ${error}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
console.log(`
|
|
154
|
+
\u2728 Done! Skills installed to: ${targetDir}`);
|
|
155
|
+
}
|
|
156
|
+
async function executeSkill(skillCommand) {
|
|
157
|
+
const fullCommand = `claude "${skillCommand}"`;
|
|
158
|
+
console.log(`Executing: ${fullCommand}
|
|
159
|
+
`);
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
const child = (0, import_child_process.spawn)("claude", [skillCommand], {
|
|
162
|
+
stdio: "inherit",
|
|
163
|
+
shell: true
|
|
164
|
+
});
|
|
165
|
+
child.on("close", (code) => {
|
|
166
|
+
if (code === 0) {
|
|
167
|
+
resolve();
|
|
168
|
+
} else {
|
|
169
|
+
reject(new Error(`Command failed with code ${code}`));
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
child.on("error", (error) => {
|
|
173
|
+
reject(error);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/cli.ts
|
|
179
|
+
import_commander.program.name("unityclaw-skills").description("UnityClaw Skills - Install and execute skills for Claude Code and OpenClaw").version("1.0.0");
|
|
180
|
+
import_commander.program.command("install [skills...]").description("Install skills to Claude Code or OpenClaw").option("-t, --target <target>", "Target platform: claude or openclaw", "claude").action(async (skills, options) => {
|
|
181
|
+
if (options.target !== "claude" && options.target !== "openclaw") {
|
|
182
|
+
console.error(`Error: Invalid target "${options.target}". Use "claude" or "openclaw".`);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
await installSkills(options.target, skills);
|
|
186
|
+
});
|
|
187
|
+
import_commander.program.command("list").description("List all available skills").action(async () => {
|
|
188
|
+
const skills = await listSkills();
|
|
189
|
+
console.log("\nAvailable skills:\n");
|
|
190
|
+
for (const skill of skills) {
|
|
191
|
+
const emoji = skill.meta?.metadata?.openclaw?.emoji || "\u{1F4E6}";
|
|
192
|
+
console.log(` ${emoji} ${skill.name}`);
|
|
193
|
+
if (skill.meta?.description) {
|
|
194
|
+
console.log(` ${skill.meta.description}`);
|
|
195
|
+
}
|
|
196
|
+
console.log();
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
import_commander.program.command("update").description("Update @unityclaw/sdk and @unityclaw/skills to the latest version").option("-g, --global", "Update globally installed packages").action(async (options) => {
|
|
200
|
+
console.log("Updating @unityclaw packages...\n");
|
|
201
|
+
const useGlobal = options.global ? ["-g"] : [];
|
|
202
|
+
const packages = ["@unityclaw/sdk", "@unityclaw/skills"];
|
|
203
|
+
for (const pkg of packages) {
|
|
204
|
+
console.log(`Updating ${pkg}...`);
|
|
205
|
+
try {
|
|
206
|
+
await new Promise((resolve, reject) => {
|
|
207
|
+
const child = (0, import_child_process2.spawn)("npm", ["install", ...useGlobal, `${pkg}@latest`], {
|
|
208
|
+
stdio: "inherit",
|
|
209
|
+
shell: true
|
|
210
|
+
});
|
|
211
|
+
child.on("close", (code) => {
|
|
212
|
+
if (code === 0) {
|
|
213
|
+
console.log(`\u2705 ${pkg} updated successfully
|
|
214
|
+
`);
|
|
215
|
+
resolve();
|
|
216
|
+
} else {
|
|
217
|
+
reject(new Error(`Failed to update ${pkg}`));
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
child.on("error", reject);
|
|
221
|
+
});
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error(`\u274C Failed to update ${pkg}:`, error);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
console.log("\n\u2728 Update complete!");
|
|
227
|
+
});
|
|
228
|
+
var args = process.argv.slice(2);
|
|
229
|
+
if (args.length > 0 && args[0].startsWith("/")) {
|
|
230
|
+
const skillCommand = args.join(" ");
|
|
231
|
+
executeSkill(skillCommand).catch((error) => {
|
|
232
|
+
console.error("Error executing skill:", error);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
import_commander.program.parse();
|
|
237
|
+
}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
executeSkill,
|
|
4
|
+
installSkills,
|
|
5
|
+
listSkills
|
|
6
|
+
} from "./chunk-KHQZYC3Y.js";
|
|
7
|
+
|
|
8
|
+
// src/cli.ts
|
|
9
|
+
import { program } from "commander";
|
|
10
|
+
import { spawn } from "child_process";
|
|
11
|
+
program.name("unityclaw-skills").description("UnityClaw Skills - Install and execute skills for Claude Code and OpenClaw").version("1.0.0");
|
|
12
|
+
program.command("install [skills...]").description("Install skills to Claude Code or OpenClaw").option("-t, --target <target>", "Target platform: claude or openclaw", "claude").action(async (skills, options) => {
|
|
13
|
+
if (options.target !== "claude" && options.target !== "openclaw") {
|
|
14
|
+
console.error(`Error: Invalid target "${options.target}". Use "claude" or "openclaw".`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
await installSkills(options.target, skills);
|
|
18
|
+
});
|
|
19
|
+
program.command("list").description("List all available skills").action(async () => {
|
|
20
|
+
const skills = await listSkills();
|
|
21
|
+
console.log("\nAvailable skills:\n");
|
|
22
|
+
for (const skill of skills) {
|
|
23
|
+
const emoji = skill.meta?.metadata?.openclaw?.emoji || "\u{1F4E6}";
|
|
24
|
+
console.log(` ${emoji} ${skill.name}`);
|
|
25
|
+
if (skill.meta?.description) {
|
|
26
|
+
console.log(` ${skill.meta.description}`);
|
|
27
|
+
}
|
|
28
|
+
console.log();
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
program.command("update").description("Update @unityclaw/sdk and @unityclaw/skills to the latest version").option("-g, --global", "Update globally installed packages").action(async (options) => {
|
|
32
|
+
console.log("Updating @unityclaw packages...\n");
|
|
33
|
+
const useGlobal = options.global ? ["-g"] : [];
|
|
34
|
+
const packages = ["@unityclaw/sdk", "@unityclaw/skills"];
|
|
35
|
+
for (const pkg of packages) {
|
|
36
|
+
console.log(`Updating ${pkg}...`);
|
|
37
|
+
try {
|
|
38
|
+
await new Promise((resolve, reject) => {
|
|
39
|
+
const child = spawn("npm", ["install", ...useGlobal, `${pkg}@latest`], {
|
|
40
|
+
stdio: "inherit",
|
|
41
|
+
shell: true
|
|
42
|
+
});
|
|
43
|
+
child.on("close", (code) => {
|
|
44
|
+
if (code === 0) {
|
|
45
|
+
console.log(`\u2705 ${pkg} updated successfully
|
|
46
|
+
`);
|
|
47
|
+
resolve();
|
|
48
|
+
} else {
|
|
49
|
+
reject(new Error(`Failed to update ${pkg}`));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
child.on("error", reject);
|
|
53
|
+
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error(`\u274C Failed to update ${pkg}:`, error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
console.log("\n\u2728 Update complete!");
|
|
59
|
+
});
|
|
60
|
+
var args = process.argv.slice(2);
|
|
61
|
+
if (args.length > 0 && args[0].startsWith("/")) {
|
|
62
|
+
const skillCommand = args.join(" ");
|
|
63
|
+
executeSkill(skillCommand).catch((error) => {
|
|
64
|
+
console.error("Error executing skill:", error);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
program.parse();
|
|
69
|
+
}
|