@moon791017/neo-skills 1.0.25 → 1.0.27

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.
@@ -0,0 +1,32 @@
1
+ import { parseArgs } from 'node:util';
2
+
3
+ /**
4
+ * 集中設定全域錯誤攔截,確保非預期錯誤不會靜默失敗
5
+ */
6
+ export function setupGlobalErrorHandlers() {
7
+ process.on('uncaughtException', (err) => {
8
+ console.error('💥 [Fatal Error]:', err);
9
+ process.exit(1);
10
+ });
11
+ process.on('unhandledRejection', (reason) => {
12
+ console.error('💥 [Unhandled Rejection]:', reason);
13
+ process.exit(1);
14
+ });
15
+ }
16
+
17
+ /**
18
+ * 解析 CLI 參數,支援 --ai-agent, --project-path, --instructions
19
+ * 允許使用等號賦值 (e.g. --ai-agent=claude) 或空格 (e.g. --ai-agent claude)
20
+ * @returns {{ [key: string]: string | boolean | undefined }} 解析後的參數物件
21
+ */
22
+ export function parseCliArgs() {
23
+ const { values } = parseArgs({
24
+ options: {
25
+ 'ai-agent': { type: 'string' },
26
+ 'project-path': { type: 'string' },
27
+ 'instructions': { type: 'string' },
28
+ },
29
+ strict: false // 允許未定義的參數,避免因為傳入未知的 flag 導致 crash
30
+ });
31
+ return values;
32
+ }
package/bin/_utils.js CHANGED
@@ -71,7 +71,7 @@ export const AGENTS = {
71
71
  * @param {object} config - AGENTS 中的 agent 設定物件
72
72
  * @param {string} [targetPath] - 使用者透過 --project-path 指定的自訂根目錄
73
73
  */
74
- export function createInstaller({ name: agentName, homePath, projectPath, hint }, targetPath) {
74
+ export function createInstaller({ name: agentName, homePath, projectPath, hint }, cliBasePath) {
75
75
  return async function install() {
76
76
  console.log(`🚀 [${agentName}] 開始同步 Neo Skills...`);
77
77
 
@@ -84,9 +84,9 @@ export function createInstaller({ name: agentName, homePath, projectPath, hint }
84
84
  }
85
85
 
86
86
  // 根目錄:--project-path 優先,否則 $HOME
87
- const baseDir = targetPath ? resolve(targetPath) : homedir();
87
+ const baseDir = cliBasePath ? resolve(cliBasePath) : homedir();
88
88
  // 子目錄:專案層級有獨立路徑時採用 projectPath,否則用預設的 homePath
89
- const subDir = targetPath && projectPath ? projectPath : homePath;
89
+ const subDir = cliBasePath && projectPath ? projectPath : homePath;
90
90
  const targetSkillsDir = join(baseDir, subDir);
91
91
 
92
92
  console.log(`📁 來源路徑: ${sourceDir}`);
@@ -111,7 +111,7 @@ export function createInstaller({ name: agentName, homePath, projectPath, hint }
111
111
  return { success: true, message: '沒有任何檔案被複製' };
112
112
  }
113
113
 
114
- const displayPath = targetPath || homePath;
114
+ const displayPath = cliBasePath || homePath;
115
115
  const msg = `已同步 ${copyCount} 個檔案/資料夾至 ${displayPath}`;
116
116
  console.log(`✅ [${agentName}] 安裝成功!${msg}`);
117
117
  if (hint) console.log(`💡 提示: ${hint}`);
@@ -14,34 +14,15 @@
14
14
  * 省略時安裝至全域路徑。
15
15
  */
16
16
  import { AGENTS, createInstaller } from './_utils.js';
17
+ import { setupGlobalErrorHandlers, parseCliArgs } from './_cli-utils.js';
17
18
 
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
- // 全域錯誤攔截,確保非預期錯誤不會靜默失敗
31
- process.on('uncaughtException', (err) => {
32
- console.error('💥 [Fatal Error]:', err);
33
- process.exit(1);
34
- });
35
- process.on('unhandledRejection', (reason) => {
36
- console.error('💥 [Unhandled Rejection]:', reason);
37
- process.exit(1);
38
- });
19
+ setupGlobalErrorHandlers();
39
20
 
40
21
  async function main() {
41
- // 先統一解析 CLI 參數,後續分支都使用同一份輸入來源,
42
- // 避免在不同模式中重複讀取 process.argv。
43
- const agentKey = parseArg('--ai-agent');
44
- const projectPath = parseArg('--project-path');
22
+ // 統一解析 CLI 參數
23
+ const args = parseCliArgs();
24
+ const agentKey = args['ai-agent'];
25
+ const projectPath = args['project-path'];
45
26
 
46
27
  // ── 模式一:指定單一 agent ──
47
28
  if (agentKey) {
@@ -19,17 +19,9 @@ import { homedir } from 'node:os';
19
19
 
20
20
  import { AGENTS } from './_utils.js';
21
21
  import { INSTRUCTIONS } from './_system-instructions.js';
22
+ import { setupGlobalErrorHandlers, parseCliArgs } from './_cli-utils.js';
22
23
 
23
- /**
24
- * 從 process.argv 解析指定 flag 的值。
25
- * @param {string} flag
26
- * @returns {string | undefined}
27
- */
28
- function parseArg(flag) {
29
- const idx = process.argv.indexOf(flag);
30
- if (idx === -1 || idx + 1 >= process.argv.length) return undefined;
31
- return process.argv[idx + 1];
32
- }
24
+ setupGlobalErrorHandlers();
33
25
 
34
26
  /**
35
27
  * 產生提示詞的起始標記。
@@ -56,16 +48,6 @@ function wrapContent(key, content) {
56
48
  return `${startMarker(key)}\n${content}\n${endMarker(key)}`;
57
49
  }
58
50
 
59
- // 全域錯誤攔截
60
- process.on('uncaughtException', (err) => {
61
- console.error('💥 [Fatal Error]:', err);
62
- process.exit(1);
63
- });
64
- process.on('unhandledRejection', (reason) => {
65
- console.error('💥 [Unhandled Rejection]:', reason);
66
- process.exit(1);
67
- });
68
-
69
51
  /**
70
52
  * 對單一 agent 執行系統提示詞安裝。
71
53
  *
@@ -127,9 +109,10 @@ async function installForAgent(agentKey, agentConfig, instructionsKey, instructi
127
109
  }
128
110
 
129
111
  async function main() {
130
- const agentKey = parseArg('--ai-agent');
131
- const projectPath = parseArg('--project-path');
132
- const instructionsKey = parseArg('--instructions');
112
+ const args = parseCliArgs();
113
+ const agentKey = args['ai-agent'];
114
+ const projectPath = args['project-path'];
115
+ const instructionsKey = args['instructions'];
133
116
 
134
117
  // ── 驗證 --instructions(兩種模式皆需要)──
135
118
  if (!instructionsKey) {