@moon791017/neo-skills 1.0.19 → 1.0.20

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Neo Skills
2
2
 
3
+ [![test-on-develop](https://github.com/Benknightdark/neo-skills/actions/workflows/test-on-develop.yml/badge.svg)](https://github.com/Benknightdark/neo-skills/actions/workflows/test-on-develop.yml)
4
+
3
5
  **Neo Skills** 是專為現代 **AI Agent** 設計的**全方位能力擴充套件**。本專案透過標準化的通訊架構,為 AI 代理安裝可插拔的「技能模組 (Skills)」,使其不僅僅是一個聊天機器人,而是能轉化為具備「感知-推理-行動」能力的**多領域專家**。
4
6
 
5
7
  無論是 DevOps 自動化、軟體架構設計,或是未來的資料分析與專案管理,Neo Skills 都能透過掛載不同的知識庫與工具,讓 AI 成為您最強大的全能助手。
@@ -74,42 +76,36 @@
74
76
  gemini extension install https://github.com/Benknightdark/neo-skills --auto-update
75
77
  ```
76
78
 
77
- ### Claude Code
79
+ ### 安裝指定 AI Agent 技能
78
80
 
79
- ```bash
80
- npx -p @moon791017/neo-skills install-claude-skills
81
- ```
82
-
83
- ### Copilot CLI
81
+ 使用 `--ai-agent` 指定要安裝的 agent(可用值:`claude`、`copilot`、`codex`):
84
82
 
85
83
  ```bash
86
- npx -p @moon791017/neo-skills install-copilot-skills
87
- ```
88
-
89
- ### Codex CLI
90
-
91
- ```bash
92
- npx -p @moon791017/neo-skills install-codex-skills
84
+ npx -p @moon791017/neo-skills install-skills --ai-agent claude
85
+ npx -p @moon791017/neo-skills install-skills --ai-agent copilot
86
+ npx -p @moon791017/neo-skills install-skills --ai-agent codex
93
87
  ```
94
88
 
95
89
  ### 安裝至指定專案
96
90
 
97
- Claude Code、Copilot CLI、Codex CLI 三種安裝指令皆支援 `--project-path` 參數,可將技能安裝至指定專案目錄。技能子目錄會自動附加:
91
+ 搭配 `--project-path` 可將技能安裝至指定專案目錄(技能子目錄會自動附加):
98
92
 
99
93
  ```bash
100
94
  # 安裝至 /my/project/.claude/skills
101
- npx -p @moon791017/neo-skills install-claude-skills --project-path /my/project
95
+ npx -p @moon791017/neo-skills install-skills --ai-agent claude --project-path /my/project
102
96
 
103
97
  # 安裝至 /my/project/.github/skills
104
- npx -p @moon791017/neo-skills install-copilot-skills --project-path /my/project
98
+ npx -p @moon791017/neo-skills install-skills --ai-agent copilot --project-path /my/project
105
99
 
106
100
  # 安裝至 /my/project/.codex/skills
107
- npx -p @moon791017/neo-skills install-codex-skills --project-path /my/project
101
+ npx -p @moon791017/neo-skills install-skills --ai-agent codex --project-path /my/project
108
102
  ```
109
103
 
110
104
  若未指定 `--project-path`,則安裝至全域路徑(`~/.claude/skills`、`~/.copilot/skills`、`~/.codex/skills`)。
111
105
 
112
- ### 安裝全部AI Agent技能
106
+ ### 安裝全部 AI Agent 技能
107
+
108
+ 不帶 `--ai-agent` 即可一次安裝全部:
113
109
 
114
110
  ```bash
115
111
  npx -p @moon791017/neo-skills install-skills
package/bin/_utils.js CHANGED
@@ -1,24 +1,17 @@
1
1
  /**
2
2
  * Shared utilities for agent skill installers.
3
- *
4
- * 新增 AI agent 只需兩步:
5
- * 1. 在 AGENTS 加入設定
6
- * 2. 建立 bin/install-{key}-skills.js(複製任一現有檔案,改 named export 即可)
7
3
  */
8
- import { realpathSync } from 'node:fs';
9
4
  import { cp, mkdir, access } from 'node:fs/promises';
10
- import { join, resolve, dirname, basename } from 'node:path';
5
+ import { join, resolve, dirname } from 'node:path';
11
6
  import { homedir } from 'node:os';
12
7
  import { fileURLToPath } from 'node:url';
13
8
 
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = dirname(__filename);
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
10
  const packageRoot = resolve(__dirname, '..');
17
11
  const sourceDir = join(packageRoot, 'skills');
18
12
 
19
13
  /**
20
14
  * Agent 設定中心 — 所有 agent 的安裝參數集中管理於此。
21
- * key 須與檔名 install-{key}-skills.js 一致。
22
15
  *
23
16
  * 各欄位說明:
24
17
  * name — 顯示用名稱,用於 CLI 輸出的 log 標籤。
@@ -45,33 +38,8 @@ export const AGENTS = {
45
38
  homePath: '.codex/skills',
46
39
  hint: '請確保您的 Codex CLI 已指向此目錄。',
47
40
  },
48
- // gemini: {
49
- // name: 'Gemini',
50
- // homePath: '.gemini/skills/neo-skills',
51
- // hint: '請確保您的 Gemini CLI 已指向此目錄。',
52
- // },
53
41
  };
54
42
 
55
- /**
56
- * 從 CLI 參數解析 --project-path 值
57
- * @returns {string | undefined}
58
- */
59
- function parseProjectPath() {
60
- const idx = process.argv.indexOf('--project-path');
61
- if (idx === -1 || idx + 1 >= process.argv.length) return undefined;
62
- return process.argv[idx + 1];
63
- }
64
-
65
- /**
66
- * 從檔名解析 agent key: install-{key}-skills.js → key
67
- */
68
- function extractAgentKey(importMetaUrl) {
69
- const filename = basename(fileURLToPath(importMetaUrl), '.js');
70
- const match = filename.match(/^install-(.+)-skills$/);
71
- if (!match) throw new Error(`無法從檔名 "${filename}" 解析 agent key`);
72
- return match[1];
73
- }
74
-
75
43
  /**
76
44
  * 根據 agent config 建立 installer 函式。
77
45
  *
@@ -85,8 +53,8 @@ function extractAgentKey(importMetaUrl) {
85
53
  * 3. 最終安裝路徑 = baseDir + subDir
86
54
  *
87
55
  * 範例(以 Copilot 為例):
88
- * 預設: ~/.copilot/skills (homedir + homePath)
89
- * --project-path /my/project: /my/project/.github/skills targetPath + projectPath)
56
+ * 預設: ~/.copilot/skills (homedir + homePath)
57
+ * --project-path /my/project: /my/project/.github/skills projectPath + projectPath)
90
58
  *
91
59
  * @param {object} config - AGENTS 中的 agent 設定物件
92
60
  * @param {string} [targetPath] - 使用者透過 --project-path 指定的自訂根目錄
@@ -138,55 +106,3 @@ export function createInstaller({ name: agentName, homePath, projectPath, hint }
138
106
  return { success: true, message: msg };
139
107
  };
140
108
  }
141
-
142
- /**
143
- * 從呼叫端的檔名自動解析 agent,建立對應的 installer。
144
- * @param {string} importMetaUrl - 呼叫端的 import.meta.url
145
- * @param {string} [targetPath] - 使用者透過 --project-path 指定的自訂路徑
146
- */
147
- export function createInstallerFromFile(importMetaUrl, targetPath) {
148
- const key = extractAgentKey(importMetaUrl);
149
- const config = AGENTS[key];
150
- if (!config) throw new Error(`未知的 agent: "${key}"。請在 _utils.js 的 AGENTS 中註冊。`);
151
- return createInstaller(config, targetPath);
152
- }
153
-
154
- /**
155
- * 當腳本被直接執行時(非 import),自動呼叫 installer。
156
- * Agent 名稱從檔名自動推導。
157
- * @param {() => Promise<{ success: boolean, message: string }>} installFn
158
- * @param {string} callerUrl - 呼叫端的 import.meta.url
159
- */
160
- export function runAsMain(installFn, callerUrl) {
161
- const callerPath = fileURLToPath(callerUrl);
162
- const argvPath = process.argv[1];
163
- const isMain = Boolean(argvPath) && (
164
- resolve(argvPath) === resolve(callerPath) ||
165
- realpathSync.native(resolve(argvPath)) === realpathSync.native(resolve(callerPath))
166
- );
167
- if (!isMain) return;
168
-
169
- const key = extractAgentKey(callerUrl);
170
- const agentName = AGENTS[key]?.name || key;
171
-
172
- process.on('uncaughtException', (err) => {
173
- console.error('💥 [Fatal Error]:', err);
174
- process.exit(1);
175
- });
176
- process.on('unhandledRejection', (reason) => {
177
- console.error('💥 [Unhandled Rejection]:', reason);
178
- process.exit(1);
179
- });
180
-
181
- const targetPath = parseProjectPath();
182
- const actualInstallFn = targetPath
183
- ? createInstallerFromFile(callerUrl, targetPath)
184
- : installFn;
185
-
186
- actualInstallFn().then((result) => {
187
- if (!result.success) process.exit(1);
188
- }).catch((error) => {
189
- console.error(`❌ [${agentName}] 安裝失敗:`, error.message || error);
190
- process.exit(1);
191
- });
192
- }
@@ -1,17 +1,67 @@
1
1
  #!/usr/bin/env node
2
+ /**
3
+ * Neo Skills 統一安裝程式
4
+ *
5
+ * 用法:
6
+ * install-skills 安裝全部 AI Agent 技能至 $HOME
7
+ * install-skills --ai-agent claude 只安裝 Claude 技能至 $HOME
8
+ * install-skills --ai-agent copilot --project-path . 安裝 Copilot 技能至指定專案
9
+ *
10
+ * 參數:
11
+ * --ai-agent <name> 指定要安裝的 agent(可用值見 _utils.js 的 AGENTS)。
12
+ * 省略時安裝全部 agent。
13
+ * --project-path <path> 指定專案根目錄作為安裝基底(取代 $HOME)。
14
+ * 省略時安裝至全域路徑。
15
+ */
2
16
  import { AGENTS, createInstaller } from './_utils.js';
3
17
 
18
+ /**
19
+ * 從 process.argv 解析指定 flag 的值。
20
+ * 例如 parseArg('--ai-agent') 在 argv 含 ['--ai-agent', 'claude'] 時回傳 'claude'。
21
+ * @param {string} flag
22
+ * @returns {string | undefined}
23
+ */
24
+ function parseArg(flag) {
25
+ const idx = process.argv.indexOf(flag);
26
+ if (idx === -1 || idx + 1 >= process.argv.length) return undefined;
27
+ return process.argv[idx + 1];
28
+ }
29
+
30
+ // 全域錯誤攔截,確保非預期錯誤不會靜默失敗
4
31
  process.on('uncaughtException', (err) => {
5
32
  console.error('💥 [Fatal Error]:', err);
6
33
  process.exit(1);
7
34
  });
8
-
9
35
  process.on('unhandledRejection', (reason) => {
10
36
  console.error('💥 [Unhandled Rejection]:', reason);
11
37
  process.exit(1);
12
38
  });
13
39
 
14
40
  async function main() {
41
+ // 先統一解析 CLI 參數,後續分支都使用同一份輸入來源,
42
+ // 避免在不同模式中重複讀取 process.argv。
43
+ const agentKey = parseArg('--ai-agent');
44
+ const projectPath = parseArg('--project-path');
45
+
46
+ // ── 模式一:指定單一 agent ──
47
+ if (agentKey) {
48
+ // 以 AGENTS 作為唯一白名單來源,避免使用者輸入未支援的 agent 名稱。
49
+ const config = AGENTS[agentKey];
50
+ if (!config) {
51
+ const valid = Object.keys(AGENTS).join(', ');
52
+ console.error(`❌ 未知的 agent: "${agentKey}"。可用選項: ${valid}`);
53
+ process.exit(1);
54
+ }
55
+
56
+ // createInstaller 會根據 agent 設定與 projectPath
57
+ // 回傳對應的安裝函式,這裡只需執行一次即可完成單一 agent 安裝。
58
+ const installFn = createInstaller(config, projectPath);
59
+ const result = await installFn();
60
+ if (!result.success) process.exit(1);
61
+ return;
62
+ }
63
+
64
+ // ── 模式二:安裝全部 agent ──
15
65
  console.log('╔══════════════════════════════════════════╗');
16
66
  console.log('║ 🧠 Neo Skills — 統一安裝程式 ║');
17
67
  console.log('╚══════════════════════════════════════════╝');
@@ -19,10 +69,12 @@ async function main() {
19
69
 
20
70
  const results = [];
21
71
 
22
- for (const [key, config] of Object.entries(AGENTS)) {
72
+ // 未指定 --ai-agent 時,逐一嘗試安裝所有已註冊 agent。
73
+ // 每個 agent 的錯誤都獨立處理,確保單一失敗不會中斷整體彙總流程。
74
+ for (const [, config] of Object.entries(AGENTS)) {
23
75
  console.log(`━━━ 正在安裝: ${config.name} ━━━`);
24
76
  try {
25
- const installFn = createInstaller(config);
77
+ const installFn = createInstaller(config, projectPath);
26
78
  const result = await installFn();
27
79
  results.push({ name: config.name, ...result });
28
80
  } catch (error) {
@@ -37,6 +89,7 @@ async function main() {
37
89
  console.log('📊 安裝結果彙總:');
38
90
  const failed = results.filter(r => !r.success);
39
91
 
92
+ // 統一列出每個 agent 的最終結果,讓使用者能快速判斷成功與失敗原因。
40
93
  for (const r of results) {
41
94
  console.log(` ${r.success ? '✅' : '❌'} ${r.name}: ${r.message}`);
42
95
  }
@@ -52,4 +105,5 @@ async function main() {
52
105
  console.log('🎉 全部安裝完成!');
53
106
  }
54
107
 
108
+ // 以單一入口啟動 CLI,讓所有例外都集中經過上方的全域錯誤處理。
55
109
  main();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "neo-skills",
3
3
  "description": "A universal capability extension for Gemini CLI",
4
- "version": "0.47.1",
4
+ "version": "0.47.3",
5
5
  "mcpServers": {
6
6
  "neo-skills": {
7
7
  "command": "node",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moon791017/neo-skills",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "type": "module",
5
5
  "description": "Neo Skills: A Universal Expert Agent Extension",
6
6
  "homepage": "https://neo-blog-iota.vercel.app/",
@@ -12,10 +12,7 @@
12
12
  ],
13
13
  "bin": {
14
14
  "neo-skills": "./bin/install-skills.js",
15
- "install-skills": "./bin/install-skills.js",
16
- "install-claude-skills": "./bin/install-claude-skills.js",
17
- "install-copilot-skills": "./bin/install-copilot-skills.js",
18
- "install-codex-skills": "./bin/install-codex-skills.js"
15
+ "install-skills": "./bin/install-skills.js"
19
16
  },
20
17
  "files": [
21
18
  "dist",
@@ -38,7 +35,7 @@
38
35
  "start": "node dist/server.js",
39
36
  "dev": "bun src/server.ts",
40
37
  "typecheck": "tsc --noEmit",
41
- "test": "echo \"No tests specified\" && exit 0"
38
+ "test": "node --test"
42
39
  },
43
40
  "devDependencies": {
44
41
  "@types/bun": "latest",
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createInstallerFromFile, runAsMain } from './_utils.js';
3
-
4
- export const install = createInstallerFromFile(import.meta.url);
5
- export { install as installClaudeSkills };
6
-
7
- runAsMain(install, import.meta.url);
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createInstallerFromFile, runAsMain } from './_utils.js';
3
-
4
- export const install = createInstallerFromFile(import.meta.url);
5
- export { install as installCodexSkills };
6
-
7
- runAsMain(install, import.meta.url);
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createInstallerFromFile, runAsMain } from './_utils.js';
3
-
4
- export const install = createInstallerFromFile(import.meta.url);
5
- export { install as installCopilotSkills };
6
-
7
- runAsMain(install, import.meta.url);