xc-skills 1.0.0 → 1.0.6

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 (3) hide show
  1. package/README.md +93 -0
  2. package/dist/cli.js +1 -1
  3. package/package.json +5 -2
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # xc-skills 🚀
2
+
3
+ 一款专门为 XC 开发团队定制的 Agent 技能管理 CLI 工具。它模仿了官方 `skills` 的交互体验,但内置了团队常用的开发工具配置,并提供了更细致的安装控制。
4
+
5
+ ## ✨ 核心特性
6
+
7
+ - **内置 Agent 支持**:默认支持 `Antigravity`, `Trae`, `Codex`, `Claude Code` 等工具。
8
+ - **全平台远程安装**:支持从 GitHub, GitLab 以及通用 Git 平台(如 **Coding.net**, 企业级私有仓库)下载并安装技能。
9
+ - **项目级安装 (Project Scope)**:支持将技能安装到当前项目的 `.agent/skills`, `.trae/skills` 等隐藏目录下。
10
+ - **技能描述预览**:在安装选择界面,自动解析并显示每个技能的详细功能描述。
11
+ - **自定义目录扫描**:支持通过 `--dir` 选项指定本地或远程仓库中的技能存放路径。
12
+ - **深度交互流程**:
13
+ 1. **Select Skills**:勾选技能(带描述预览)。
14
+ 2. **Select Agents**:选择要同步的目标开发工具。
15
+ 3. **Scope Choice**:决定是全局安装还是项目内安装。
16
+ 4. **Method Choice**:选择软链接或物理拷贝。
17
+ 5. **Summary**:安装前的详细综述。
18
+ 6. **Confirmation**:二次确认。
19
+
20
+ ## 📦 安装
21
+
22
+ 你可以通过 npm 全局安装:
23
+
24
+ ```bash
25
+ npm install -g xc-skills
26
+ ```
27
+
28
+ 或者使用 `pnpm dlx` 临时执行:
29
+
30
+ ```bash
31
+ pnpm dlx xc-skills add .
32
+ ```
33
+
34
+ ## 🚀 使用指南
35
+
36
+ ### 1. 基础添加命令
37
+
38
+ 在存放技能(含有 `skills/` 文件夹)的项目根目录下运行:
39
+
40
+ ```bash
41
+ xc-skills add .
42
+ ```
43
+
44
+ ### 2. 从 GitHub/Coding.net 安装
45
+
46
+ 直接传入仓库地址,即可快速同步远程技能库:
47
+
48
+ ```bash
49
+ # GitHub
50
+ xc-skills add https://github.com/vuejs-ai/skills.git
51
+
52
+ # Coding.net (企业级 Git 平台)
53
+ xc-skills add https://e.coding.net/your-team/skills.git
54
+ ```
55
+
56
+ ### 3. 自定义技能目录
57
+
58
+ 如果技能不在 `skills/` 目录下(例如在 `my-rules/` 目录),可以使用 `--dir` 参数:
59
+
60
+ ```bash
61
+ xc-skills add . --dir my-rules
62
+ ```
63
+
64
+ ### 4. 指定输出路径
65
+
66
+ 如果你想把技能安装到一个特定的文件夹(而不是默认的 Agent 路径或 `.agent/skills`),可以使用 `--out` 参数:
67
+
68
+ ```bash
69
+ xc-skills add . --out ./my-debug-folder
70
+ ```
71
+
72
+ ### 5. 参数化运行
73
+
74
+ ```bash
75
+ # 自动安装所有技能到 Antigravity(跳过交互)
76
+ xc-skills add . --yes --agent Antigravity --skill *
77
+ ```
78
+
79
+ ## 🛠 命令选项
80
+
81
+ | 选项 | 描述 |
82
+ | --- | --- |
83
+ | `-s, --skill <names>` | 指定要安装的技能名称(逗号分隔,或用 `*` 表示全部) |
84
+ | `-a, --agent <names>` | 指定目标 Agent 名称(逗号分隔,或用 `*` 表示全部) |
85
+ | `-d, --dir <dir>` | 指定源目录中技能存放的目录名(默认为 `skills`) |
86
+ | `-o, --out <path>` | 指定输出的目标目录路径 |
87
+ | `-y, --yes` | 跳过所有确认和交互步骤,使用默认值 |
88
+ | `-v, --version` | 查看版本号 |
89
+ | `-h, --help` | 查看帮助信息 |
90
+
91
+ ## 📄 License
92
+
93
+ MIT
package/dist/cli.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{cac as N}from"cac";import*as e from"@clack/prompts";import n from"picocolors";import C from"fs-extra";import{join as S,resolve as F,dirname as G,basename as O}from"path";import A from"os";import k from"os";import{join as u}from"path";var h=[{name:"Antigravity",path:u(k.homedir(),".agent/skills"),description:"Custom AI agent for XC development"},{name:"Trae",path:u(k.homedir(),".trae/skills"),description:"Trae AI IDE"},{name:"Codex",path:u(k.homedir(),".codex/skills"),description:"Codex AI assistant"},{name:"Claude Code",path:u(k.homedir(),".claude/skills"),description:"Anthropic Claude Code CLI"}];import d from"fs-extra";import{join as x,dirname as I,basename as D}from"path";import*as $ from"@clack/prompts";import E from"picocolors";import T from"os";async function b(v){let{sourceDir:s,targetAgents:y,selectedSkills:g,scope:f,method:c,strategy:o}=v,r=$.spinner();for(let l of y){let i="";if(f==="project"){let p=D(I(l.path));i=x(process.cwd(),p,"skills")}else i=l.path.replace(/^~/,T.homedir());r.start(`\u6B63\u5728\u90E8\u7F72\u5230 ${l.name} (${i})...`);try{o==="overwrite"&&await d.pathExists(i)?await d.emptyDir(i):await d.ensureDir(i);for(let p of g){let t=x(s,p),a=x(i,p);await d.pathExists(a)&&await d.remove(a),c==="symlink"?await d.ensureSymlink(t,a,"dir"):await d.copy(t,a)}r.stop(`\u6210\u529F\u540C\u6B65\u5230: ${l.name} (${f} \u6A21\u5F0F)`)}catch(p){r.stop(`${E.red("\u5931\u8D25")}: ${l.name} - ${p.message}`)}}}var w=N("xc-skills");w.command("add <source>","Add skills from a local directory").option("-s, --skill <skills>","Specific skills to install").option("-a, --agent <agents>","Specific agents to install to").option("-y, --yes","Skip confirmation prompts").action(async(v,s)=>{e.intro(`${n.bgCyan(n.black(" xc-skills "))}`);let y=F(process.cwd(),v),g=S(y,"skills");C.existsSync(g)||(e.log.error(`\u627E\u4E0D\u5230\u6280\u80FD\u76EE\u5F55: ${y}/skills`),process.exit(1));let f=(await C.readdir(g,{withFileTypes:!0})).filter(t=>t.isDirectory()&&!t.name.startsWith(".")).map(t=>t.name),c=[];s.yes||s.skill==="*"?c=f:s.skill?c=s.skill.split(","):c=await e.multiselect({message:"\u7B2C\u4E00\u6B65\uFF1A\u9009\u62E9\u8981\u5B89\u88C5\u7684\u6280\u80FD (Select skills)",options:f.map(t=>({value:t,label:t})),initialValues:[f[0]]}),e.isCancel(c)&&(e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let o=[];if(s.yes||s.agent==="*")o=h;else if(s.agent){let t=s.agent.split(",");o=h.filter(a=>t.includes(a.name))}else o=await e.multiselect({message:"\u7B2C\u4E8C\u6B65\uFF1A\u9009\u62E9\u76EE\u6807\u5F00\u53D1\u5DE5\u5177 (Select agents)",options:h.map(t=>({value:t,label:t.name,hint:t.path.replace(A.homedir(),"~")})),initialValues:[h[0]]});e.isCancel(o)&&(e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let r="project";s.yes||(r=await e.select({message:"\u7B2C\u4E09\u6B65\uFF1A\u9009\u62E9\u5B89\u88C5\u8303\u56F4 (Installation scope)",options:[{value:"project",label:"Project (\u9879\u76EE\u7EA7)",hint:"./.<agent>/skills"},{value:"global",label:"Global (\u5168\u5C40)",hint:"\u5DE5\u5177\u9ED8\u8BA4\u8DEF\u5F84"}]})),e.isCancel(r)&&(e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let l="symlink";s.yes||(l=await e.select({message:"\u7B2C\u56DB\u6B65\uFF1A\u9009\u62E9\u5B89\u88C5\u65B9\u5F0F (Installation method)",options:[{value:"symlink",label:"Symlink (\u8F6F\u94FE\u63A5 - \u63A8\u8350)",hint:"\u4E0E\u6E90\u7801\u4FDD\u6301\u5B9E\u65F6\u540C\u6B65"},{value:"copy",label:"Copy (\u7269\u7406\u62F7\u8D1D)",hint:"\u590D\u5236\u6587\u4EF6\u526F\u672C"}]})),e.isCancel(l)&&(e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let i="merge";if(!s.yes){let t=!1;for(let a of o){let m="";if(r==="project"){let j=O(G(a.path));m=S(process.cwd(),j,"skills")}else m=a.path.replace(/^~/,A.homedir());if(await C.pathExists(m)){t=!0;break}}t&&(i=await e.select({message:"\u68C0\u6D4B\u5230\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u5982\u4F55\u5904\u7406\uFF1F(Handle conflicts)",options:[{value:"merge",label:"Merge (\u5408\u5E76)",hint:"\u53EA\u66F4\u65B0\u9009\u4E2D\u7684\u6280\u80FD\uFF0C\u4FDD\u7559\u5176\u4ED6\u6280\u80FD"},{value:"overwrite",label:"Overwrite (\u8986\u76D6)",hint:"\u6E05\u7A7A\u76EE\u6807\u76EE\u5F55\u540E\u518D\u5B89\u88C5"}]}))}if(e.isCancel(i)&&(e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0)),!s.yes){e.log.message(`${n.cyan("\u5B89\u88C5\u7EFC\u8FF0 (Installation Summary)")}`),[`${n.dim("Skills:")} ${c.join(", ")}`,`${n.dim("Agents:")} ${o.map(m=>m.name).join(", ")}`,`${n.dim("Scope:")} ${r}`,`${n.dim("Method:")} ${l}`,`${n.dim("Strategy:")} ${i}`].forEach(m=>e.log.message(` ${m}`));let a=await e.confirm({message:"\u786E\u8BA4\u5B89\u88C5\uFF1F(Proceed with installation?)",initialValue:!0});(e.isCancel(a)||!a)&&(e.cancel("\u5B89\u88C5\u5DF2\u53D6\u6D88"),process.exit(0))}await b({sourceDir:g,targetAgents:o,selectedSkills:c,scope:r,method:l,strategy:i}),e.outro(n.green("\u5B89\u88C5\u5B8C\u6210\uFF01(Installation complete)"))});w.help();w.version("1.0.0");w.parse();
2
+ import{cac as F}from"cac";import*as e from"@clack/prompts";import m from"picocolors";import o from"fs-extra";import{join as w,resolve as b}from"path";import E from"os";import{execSync as M}from"child_process";import N from"degit";import S from"os";import{join as x}from"path";var v=[{name:"Antigravity",path:x(S.homedir(),".agent/skills"),description:"Custom AI agent for XC development"},{name:"Trae",path:x(S.homedir(),".trae/skills"),description:"Trae AI IDE"},{name:"Codex",path:x(S.homedir(),".codex/skills"),description:"Codex AI assistant"},{name:"Claude Code",path:x(S.homedir(),".claude/skills"),description:"Anthropic Claude Code CLI"}];import y from"fs-extra";import{join as j,dirname as R,basename as L}from"path";import*as I from"@clack/prompts";import P from"picocolors";import G from"os";async function D(l){let{sourceDir:t,targetAgents:k,selectedSkills:r,scope:s,method:$,strategy:g,customRoot:A}=l,u=I.spinner();for(let c of k){let a="";if(A)a=A;else if(s==="project"){let p=L(R(c.path));a=j(process.cwd(),p,"skills")}else a=c.path.replace(/^~/,G.homedir());u.start(`\u6B63\u5728\u90E8\u7F72\u5230 ${c.name} (${a})...`);try{g==="overwrite"&&await y.pathExists(a)?await y.emptyDir(a):await y.ensureDir(a);for(let p of r){let h=j(t,p),f=j(a,p);await y.pathExists(f)&&await y.remove(f),$==="symlink"?await y.ensureSymlink(h,f,"dir"):await y.copy(h,f)}u.stop(`\u6210\u529F\u540C\u6B65\u5230: ${c.name} (${s==="custom"?"\u81EA\u5B9A\u4E49\u8DEF\u5F84":s+" \u6A21\u5F0F"})`)}catch(p){u.stop(`${P.red("\u5931\u8D25")}: ${c.name} - ${p.message}`)}}}var C=F("xc-skills");function O(l){try{let t=w(l,"SKILL.md");if(o.existsSync(t)){let r=o.readFileSync(t,"utf-8").match(/description:\s*['"]?([^'"\n\r]+)['"]?/);return r?r[1].trim():""}}catch{}return""}C.command("add <source>","Add skills from a local directory or GitHub URL").option("-s, --skill <skills>","Specific skills to install").option("-a, --agent <agents>","Specific agents to install to").option("-d, --dir <dir>","The directory name containing skills",{default:"skills"}).option("-o, --out <path>","Specify a custom output directory").option("-y, --yes","Skip confirmation prompts").action(async(l,t)=>{e.intro(`${m.bgCyan(m.black(" xc-skills "))}`);let k="",r=!1,s=w(E.tmpdir(),`xc-skills-${Date.now()}`),$=l.startsWith("http")||l.startsWith("git@")||l.includes("/")&&!o.existsSync(b(process.cwd(),l));if($){let i=e.spinner();i.start(`\u6B63\u5728\u5C1D\u8BD5\u4E0B\u8F7D\u6280\u80FD\u5E93: ${l}`);let n=!1;try{await N(l,{cache:!1,force:!0,verbose:!1}).clone(s),n=!0,i.stop("\u4E0B\u8F7D\u6210\u529F (degit)")}catch{try{i.message("degit \u4E0D\u652F\u6301\u6B64\u5E73\u53F0\uFF0C\u6B63\u5728\u5C1D\u8BD5\u4F7F\u7528 git clone..."),M(`git clone --depth 1 ${l} ${s}`,{stdio:"ignore"}),o.existsSync(w(s,".git"))&&await o.remove(w(s,".git")),n=!0,i.stop("\u4E0B\u8F7D\u6210\u529F (git clone)")}catch(T){i.stop(m.red(`\u4E0B\u8F7D\u5931\u8D25: ${T.message}`)),process.exit(1)}}n&&(k=s,r=!0)}else k=b(process.cwd(),l);let g=w(k,t.dir);o.existsSync(g)||(e.log.error(`\u627E\u4E0D\u5230\u6280\u80FD\u76EE\u5F55: ${g}`),r&&await o.remove(s),process.exit(1));let u=(await o.readdir(g,{withFileTypes:!0})).filter(i=>i.isDirectory()&&!i.name.startsWith(".")).map(i=>{let n=i.name,d=O(w(g,n));return{name:n,description:d}});u.length===0&&(e.log.error(`\u5728 ${g} \u4E2D\u6CA1\u6709\u627E\u5230\u4EFB\u4F55\u6709\u6548\u7684\u6280\u80FD\u5B50\u76EE\u5F55`),r&&await o.remove(s),process.exit(1));let c=[];t.yes||t.skill==="*"?c=u.map(i=>i.name):t.skill?c=t.skill.split(","):c=await e.multiselect({message:"\u7B2C\u4E00\u6B65\uFF1A\u9009\u62E9\u8981\u5B89\u88C5\u7684\u6280\u80FD (Select skills)",options:u.map(i=>({value:i.name,label:i.name,hint:i.description})),initialValues:[u[0].name]}),e.isCancel(c)&&(r&&await o.remove(s),e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let a=[];if(t.out)a=[{name:"Custom Path",path:b(process.cwd(),t.out)}];else if(t.yes||t.agent==="*")a=v;else if(t.agent){let i=t.agent.split(",");a=v.filter(n=>i.includes(n.name))}else a=await e.multiselect({message:"\u7B2C\u4E8C\u6B65\uFF1A\u9009\u62E9\u76EE\u6807\u5F00\u53D1\u5DE5\u5177 (Select agents)",options:v.map(i=>({value:i,label:i.name,hint:i.path.replace(E.homedir(),"~")})),initialValues:[v[0]]});e.isCancel(a)&&(r&&await o.remove(s),e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let p=t.out?"custom":"project";!t.out&&!t.yes&&(p=await e.select({message:"\u7B2C\u4E09\u6B65\uFF1A\u9009\u62E9\u5B89\u88C5\u8303\u56F4 (Installation scope)",options:[{value:"project",label:"Project (\u9879\u76EE\u7EA7)",hint:"./.<agent>/skills"},{value:"global",label:"Global (\u5168\u5C40)",hint:"\u5DE5\u5177\u9ED8\u8BA4\u8DEF\u5F84"}]})),e.isCancel(p)&&(r&&await o.remove(s),e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let h="symlink";r?h="copy":t.yes||(h=await e.select({message:"\u7B2C\u56DB\u6B65\uFF1A\u9009\u62E9\u5B89\u88C5\u65B9\u5F0F (Installation method)",options:[{value:"symlink",label:"Symlink (\u8F6F\u94FE\u63A5 - \u63A8\u8350)",hint:"\u4E0E\u6E90\u7801\u4FDD\u6301\u5B9E\u65F6\u540C\u6B65"},{value:"copy",label:"Copy (\u7269\u7406\u62F7\u8D1D)",hint:"\u590D\u5236\u6587\u4EF6\u526F\u672C"}]})),e.isCancel(h)&&(r&&await o.remove(s),e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0));let f="merge";if(!t.yes){let i=!1;for(let n of a){let d=n.path;if(await o.pathExists(d)){i=!0;break}}i&&(f=await e.select({message:"\u68C0\u6D4B\u5230\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\uFF0C\u5982\u4F55\u5904\u7406\uFF1F(Handle conflicts)",options:[{value:"merge",label:"Merge (\u5408\u5E76)",hint:"\u53EA\u66F4\u65B0\u9009\u4E2D\u7684\u6280\u80FD\uFF0C\u4FDD\u7559\u5176\u4ED6\u6280\u80FD"},{value:"overwrite",label:"Overwrite (\u8986\u76D6)",hint:"\u6E05\u7A7A\u76EE\u6807\u76EE\u5F55\u540E\u518D\u5B89\u88C5"}]}))}if(e.isCancel(f)&&(r&&await o.remove(s),e.cancel("\u5DF2\u53D6\u6D88"),process.exit(0)),!t.yes){e.log.message(`${m.cyan("\u5B89\u88C5\u7EFC\u8FF0 (Installation Summary)")}`),[`${m.dim("Source:")} ${$?l:"Local"}`,`${m.dim("Skills:")} ${c.join(", ")}`,t.out?`${m.dim("Target:")} ${a[0].path}`:`${m.dim("Agents:")} ${a.map(d=>d.name).join(", ")}`,`${m.dim("Scope:")} ${p}`,`${m.dim("Method:")} ${h}`,`${m.dim("Strategy:")} ${f}`].forEach(d=>e.log.message(` ${d}`));let n=await e.confirm({message:"\u786E\u8BA4\u5B89\u88C5\uFF1F(Proceed with installation?)",initialValue:!0});(e.isCancel(n)||!n)&&(r&&await o.remove(s),e.cancel("\u5B89\u88C5\u5DF2\u53D6\u6D88"),process.exit(0))}await D({sourceDir:g,targetAgents:a,selectedSkills:c,scope:p,method:h,strategy:f,customRoot:t.out?b(process.cwd(),t.out):void 0}),r&&await o.remove(s),e.outro(m.green("\u5B89\u88C5\u5B8C\u6210\uFF01(Installation complete)"))});C.help();C.version("1.0.6");C.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xc-skills",
3
- "version": "1.0.0",
3
+ "version": "1.0.6",
4
4
  "description": "Custom Agent Skills CLI for XC development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,13 +17,16 @@
17
17
  "dependencies": {
18
18
  "@clack/prompts": "^1.1.0",
19
19
  "cac": "^6.7.14",
20
+ "degit": "^2.8.4",
20
21
  "fs-extra": "^11.3.0",
21
22
  "picocolors": "^1.1.1"
22
23
  },
23
24
  "devDependencies": {
25
+ "@types/degit": "^2.8.6",
24
26
  "@types/fs-extra": "^11.0.4",
25
27
  "@types/node": "^22.13.1",
28
+ "degit": "^2.8.4",
26
29
  "tsup": "^8.3.6",
27
30
  "typescript": "^5.7.3"
28
31
  }
29
- }
32
+ }