ai-developer-skill-os 1.7.1 → 1.8.1

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
@@ -57,6 +57,16 @@ Sau khi thư mục kỹ năng đã xuất hiện trong dự án của bạn, hã
57
57
  **Không cần cấu hình gì thêm!** Nếu bạn đã cài đặt bằng cờ `--gemini` (thư mục `.agents/skills/`), hệ thống sẽ tự động quét và load toàn bộ 23 kỹ năng này. Bạn có thể sử dụng ngay lập tức!
58
58
 
59
59
  ### Cho Claude Code / Kilo Code (CLI Agents)
60
+ #### Cách 1: Cài đặt Native (Khuyên dùng cho Kilo Code)
61
+ Chạy `npx ai-developer-skill-os init` và chọn **(6) Kilo Code**.
62
+ Hệ thống sẽ tự động:
63
+ - Copy toàn bộ skills vào `.kilo/skills/` (Local) hoặc `~/.kilo/skills/` (Global)
64
+ - Cấu hình `kilo.json` hoặc `~/.config/kilo/kilo.json` để Kilo nhận diện
65
+ - Tạo file `CLAUDE.md` như hướng dẫn bổ sung
66
+
67
+ Sau đó mở Kilo Code, dùng `<leader>t` hoặc `/themes` để kiểm tra skills đã được cài.
68
+
69
+ #### Cách 2: Thủ công
60
70
  Tạo file `CLAUDE.md` (hoặc `KILO.md`) ở gốc dự án và dán đoạn sau vào:
61
71
  ```md
62
72
  # System Instructions
package/bin/install.js CHANGED
@@ -28,19 +28,56 @@ function cleanOldSkills(targetSkillsDir, isGeminiGlobal) {
28
28
  if (fs.existsSync(targetSkillsDir)) {
29
29
  console.log('🧹 Đang dọn dẹp phiên bản cũ để tối ưu hệ thống...');
30
30
  if (isGeminiGlobal) {
31
- // Chỉ xoá các thư mục qk-* để không ảnh hưởng các skill khác của người dùng
32
31
  fs.readdirSync(targetSkillsDir).forEach(item => {
33
32
  if (item.startsWith('qk-')) {
34
33
  fs.rmSync(path.join(targetSkillsDir, item), { recursive: true, force: true });
35
34
  }
36
35
  });
37
36
  } else {
38
- // Xoá sạch toàn bộ thư mục kỹ năng của bộ công cụ này
39
37
  fs.rmSync(targetSkillsDir, { recursive: true, force: true });
40
38
  }
41
39
  }
42
40
  }
43
41
 
42
+ function ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir) {
43
+ if (!fs.existsSync(kiloSkillsDir)) {
44
+ fs.mkdirSync(kiloSkillsDir, { recursive: true });
45
+ }
46
+ if (!fs.existsSync(kiloThemesDir)) {
47
+ fs.mkdirSync(kiloThemesDir, { recursive: true });
48
+ }
49
+ if (!fs.existsSync(kiloCommandsDir)) {
50
+ fs.mkdirSync(kiloCommandsDir, { recursive: true });
51
+ }
52
+
53
+ const srcSkills = path.join(sourceDir, 'skills');
54
+ if (fs.existsSync(srcSkills)) {
55
+ copyRecursiveSync(srcSkills, kiloSkillsDir);
56
+ }
57
+
58
+ let kiloConfig = {};
59
+ if (fs.existsSync(kiloJsonPath)) {
60
+ try {
61
+ kiloConfig = JSON.parse(fs.readFileSync(kiloJsonPath, 'utf8'));
62
+ } catch (e) {
63
+ kiloConfig = {};
64
+ }
65
+ }
66
+
67
+ const skillPaths = [kiloSkillsDir];
68
+ if (!Array.isArray(kiloConfig.skills) || typeof kiloConfig.skills !== 'object' || !kiloConfig.skills.paths) {
69
+ kiloConfig.skills = { paths: skillPaths };
70
+ } else {
71
+ const exists = kiloConfig.skills.paths.some(p => path.resolve(p) === path.resolve(kiloSkillsDir));
72
+ if (!exists) {
73
+ kiloConfig.skills.paths = [...kiloConfig.skills.paths, ...skillPaths];
74
+ }
75
+ }
76
+
77
+ fs.writeFileSync(kiloJsonPath, JSON.stringify(kiloConfig, null, 2) + '\n');
78
+ return kiloJsonPath;
79
+ }
80
+
44
81
  const rl = readline.createInterface({
45
82
  input: process.stdin,
46
83
  output: process.stdout
@@ -55,9 +92,10 @@ const questionIde = `Vui lòng chọn IDE/AI Assistant bạn đang sử dụng:
55
92
  (4) Antigravity / Gemini
56
93
  (5) Codex
57
94
  (6) Kilo Code
95
+ (7) Tất cả các IDE (Multi-IDE)
58
96
  (0) Bỏ qua (Không tạo config tự động)
59
97
 
60
- Nhập số (0-6): `;
98
+ Nhập số (0-7): `;
61
99
 
62
100
  const questionScope = `
63
101
  Bạn muốn cài đặt bộ kỹ năng ở đâu?
@@ -68,6 +106,8 @@ Nhập số (1-2): `;
68
106
 
69
107
  rl.question(questionIde, (answerIde) => {
70
108
  let isGemini = false;
109
+ let isKilo = false;
110
+ let isMultiIde = false;
71
111
  let ruleFileName = null;
72
112
  const ideCode = answerIde.trim();
73
113
 
@@ -77,20 +117,35 @@ rl.question(questionIde, (answerIde) => {
77
117
  case '3': ruleFileName = '.clinerules'; break;
78
118
  case '4': isGemini = true; break;
79
119
  case '5': ruleFileName = '.codexrules'; break;
80
- case '6': ruleFileName = '.kilorules'; break;
120
+ case '6': ruleFileName = '.kilorules'; isKilo = true; break;
121
+ case '7': isMultiIde = true; ruleFileName = null; break;
81
122
  case '0': default: break;
82
123
  }
83
124
 
84
125
  rl.question(questionScope, (answerScope) => {
85
126
  const isGlobal = answerScope.trim() === '2';
86
127
 
128
+ const homeDir = os.homedir();
129
+ const cwd = process.cwd();
87
130
  let targetDir = '';
88
131
  let ruleFilePath = null;
89
132
  let baseFolderForPrompt = '';
90
- const homeDir = os.homedir();
91
- const cwd = process.cwd();
133
+ let kiloJsonPath = null;
134
+ let kiloSkillsDir = null;
135
+ let kiloThemesDir = null;
136
+ let kiloCommandsDir = null;
92
137
 
93
- if (isGemini) {
138
+ if (isMultiIde) {
139
+ targetDir = path.join(cwd, '.qk-ai-skill-os');
140
+ baseFolderForPrompt = './.qk-ai-skill-os';
141
+ ruleFilePath = path.join(cwd, 'CLAUDE.md');
142
+ if (!isGlobal) {
143
+ kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
144
+ kiloThemesDir = path.join(cwd, '.kilo', 'themes');
145
+ kiloCommandsDir = path.join(cwd, '.kilo', 'command');
146
+ kiloJsonPath = path.join(cwd, 'kilo.json');
147
+ }
148
+ } else if (isGemini) {
94
149
  if (isGlobal) {
95
150
  targetDir = path.join(homeDir, '.gemini', 'config');
96
151
  ruleFilePath = path.join(targetDir, 'AGENTS.md');
@@ -100,6 +155,23 @@ rl.question(questionIde, (answerIde) => {
100
155
  ruleFilePath = path.join(cwd, '.agents', 'AGENTS.md');
101
156
  baseFolderForPrompt = '.agents/skills';
102
157
  }
158
+ } else if (isKilo) {
159
+ if (isGlobal) {
160
+ targetDir = path.join(homeDir, '.qk-ai-skill-os');
161
+ baseFolderForPrompt = targetDir.replace(/\\/g, '/');
162
+ kiloSkillsDir = path.join(homeDir, '.kilo', 'skills');
163
+ kiloThemesDir = path.join(homeDir, '.config', 'kilo', 'themes');
164
+ kiloCommandsDir = path.join(homeDir, '.config', 'kilo', 'command');
165
+ kiloJsonPath = path.join(homeDir, '.config', 'kilo', 'kilo.json');
166
+ } else {
167
+ targetDir = path.join(cwd, '.qk-ai-skill-os');
168
+ baseFolderForPrompt = './.qk-ai-skill-os';
169
+ kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
170
+ kiloThemesDir = path.join(cwd, '.kilo', 'themes');
171
+ kiloCommandsDir = path.join(cwd, '.kilo', 'command');
172
+ kiloJsonPath = path.join(cwd, 'kilo.json');
173
+ }
174
+ ruleFilePath = path.join(cwd, 'CLAUDE.md');
103
175
  } else {
104
176
  if (isGlobal) {
105
177
  targetDir = path.join(homeDir, '.qk-ai-skill-os');
@@ -136,49 +208,78 @@ Nếu người dùng sử dụng tham số (argument), bạn BẮT BUỘC phải
136
208
  'skills', '_template', 'docs', 'skills.json', 'README.md', 'CHANGELOG.md', 'LICENSE'
137
209
  ];
138
210
 
139
- // Nếu là Gemini Global, chỉ cần copy skills và skills.json để tránh rác
140
211
  if (isGemini && isGlobal) {
141
212
  if (fs.existsSync(path.join(sourceDir, 'skills'))) {
142
- copyRecursiveSync(path.join(sourceDir, 'skills'), path.join(targetDir, 'skills'));
213
+ copyRecursiveSync(path.join(sourceDir, 'skills'), path.join(targetDir, 'skills'));
143
214
  }
144
215
  if (fs.existsSync(path.join(sourceDir, 'skills.json'))) {
145
- fs.copyFileSync(path.join(sourceDir, 'skills.json'), path.join(targetDir, 'skills', 'skills.json'));
216
+ fs.copyFileSync(path.join(sourceDir, 'skills.json'), path.join(targetDir, 'skills', 'skills.json'));
146
217
  }
147
218
  } else {
148
219
  filesAndFolders.forEach(item => {
149
- const src = path.join(sourceDir, item);
150
- let dest = path.join(targetDir, item);
151
- if (fs.existsSync(src)) {
152
- copyRecursiveSync(src, dest);
153
- }
220
+ const src = path.join(sourceDir, item);
221
+ let dest = path.join(targetDir, item);
222
+ if (fs.existsSync(src)) {
223
+ copyRecursiveSync(src, dest);
224
+ }
154
225
  });
155
226
  }
156
227
 
157
228
  if (ruleFilePath) {
158
- const ruleDir = path.dirname(ruleFilePath);
159
- if (ruleDir !== cwd && !fs.existsSync(ruleDir)) {
160
- fs.mkdirSync(ruleDir, { recursive: true });
161
- }
162
-
163
- let writeContent = systemPrompt;
164
- if (isGemini) {
165
- writeContent = `\n<RULE[ai_skill_os]>\n---\ntrigger: always_on\n---\n${systemPrompt}\n</RULE[ai_skill_os]>\n`;
166
- }
229
+ const ruleDir = path.dirname(ruleFilePath);
230
+ if (ruleDir !== cwd && !fs.existsSync(ruleDir)) {
231
+ fs.mkdirSync(ruleDir, { recursive: true });
232
+ }
167
233
 
168
- if (fs.existsSync(ruleFilePath)) {
169
- fs.appendFileSync(ruleFilePath, "\n\n" + writeContent);
170
- console.log(`✅ Đã GHI THÊM cấu hình tự động vào file: ${ruleFilePath}`);
171
- } else {
172
- fs.writeFileSync(ruleFilePath, writeContent);
173
- console.log(`✅ Đã TẠO MỚI file cấu hình: ${ruleFilePath}`);
174
- }
234
+ let writeContent = systemPrompt;
235
+ if (isGemini) {
236
+ writeContent = `\n<RULE[ai_skill_os]>\n---\ntrigger: always_on\n---\n${systemPrompt}\n</RULE[ai_skill_os]>\n`;
237
+ }
238
+
239
+ if (fs.existsSync(ruleFilePath)) {
240
+ fs.appendFileSync(ruleFilePath, "\n\n" + writeContent);
241
+ console.log(`✅ Đã GHI THÊM cấu hình tự động vào file: ${ruleFilePath}`);
242
+ } else {
243
+ fs.writeFileSync(ruleFilePath, writeContent);
244
+ console.log(`✅ Đã TẠO MỚI file cấu hình: ${ruleFilePath}`);
245
+ }
246
+ }
247
+
248
+ if (isKilo) {
249
+ ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir);
250
+ console.log(`✅ Đã cấu hình Kilo Code tại: ${kiloJsonPath}`);
251
+ console.log(` → Skills: ${kiloSkillsDir}`);
252
+ console.log(` → Themes: ${kiloThemesDir}`);
253
+ console.log(` → Commands: ${kiloCommandsDir}`);
254
+ }
255
+
256
+ if (isMultiIde) {
257
+ if (kiloJsonPath && kiloSkillsDir) {
258
+ ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir);
259
+ console.log(`✅ Đã cấu hình Kilo Code (Multi-IDE) tại: ${kiloJsonPath}`);
260
+ console.log(` → Skills: ${kiloSkillsDir}`);
261
+ console.log(` → Themes: ${kiloThemesDir}`);
262
+ console.log(` → Commands: ${kiloCommandsDir}`);
263
+ } else if (ruleFilePath) {
264
+ console.log(`✅ Đã tạo file cấu hình Multi-IDE: ${ruleFilePath}`);
265
+ }
175
266
  }
176
267
 
177
268
  console.log(`\n🎉 HOÀN TẤT! Dữ liệu kỹ năng đã được lưu tại: ${targetDir}`);
178
269
  if (isGlobal && !isGemini) {
179
- console.log(`💡 Lưu ý: Kỹ năng đã được cài ở cấp độ máy tính (Global). File cấu hình cục bộ (${ruleFileName}) dự án này đang trỏ thẳng về thư mục Global đó.`);
270
+ const name = ruleFilePath ? path.basename(ruleFilePath) : 'CLAUDE.md';
271
+ console.log(`💡 Lưu ý: Kỹ năng đã được cài ở cấp độ máy tính (Global). File cấu hình cục bộ (${name}) ở dự án này đang trỏ thẳng về thư mục Global đó.`);
180
272
  } else if (isGlobal && isGemini) {
181
273
  console.log(`💡 Lưu ý: Antigravity đã được cài Global. Từ nay bạn mở BẤT KỲ DỰ ÁN NÀO trên máy tính này, Antigravity cũng sẽ tự động có đủ 23 kỹ năng mà không cần cài lại!`);
274
+ } else if (isKilo) {
275
+ console.log(`💡 Lưu ý: Kilo Code đã sẵn sàng. Dùng \`<leader>t\` hoặc \`/themes\` để xem, và \`/skills\` để xem danh sách skill đã cài.`);
276
+ }
277
+
278
+ if (!isGemini && !isKilo && !isMultiIde) {
279
+ if (fs.existsSync(path.join(cwd, '.kilorules'))) {
280
+ fs.unlinkSync(path.join(cwd, '.kilorules'));
281
+ console.log(`🧹 Đã xoá file .kilorules cũ (không còn cần thiết).`);
282
+ }
182
283
  }
183
284
 
184
285
  } catch (error) {
@@ -59,6 +59,16 @@ Speak to me in Vietnamese, but write all code in English.
59
59
  ```
60
60
 
61
61
  ### Cho Claude Code / Kilo Code (CLI Agents)
62
+ #### Cách 1: Cài đặt Native (Khuyên dùng cho Kilo Code)
63
+ Chạy `npx ai-developer-skill-os init` và chọn **(6) Kilo Code**.
64
+ Hệ thống sẽ tự động:
65
+ - Copy toàn bộ skills vào `.kilo/skills/` (Local) hoặc `~/.kilo/skills/` (Global)
66
+ - Cấu hình `kilo.json` hoặc `~/.config/kilo/kilo.json` để Kilo nhận diện
67
+ - Tạo file `CLAUDE.md` như hướng dẫn bổ sung
68
+
69
+ Sau đó mở Kilo Code, dùng `<leader>t` hoặc `/themes` để kiểm tra skills đã được cài.
70
+
71
+ #### Cách 2: Thủ công
62
72
  Tạo file `CLAUDE.md` (hoặc `KILO.md`) ở gốc dự án và dán đoạn sau vào:
63
73
  ```md
64
74
  # System Instructions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-developer-skill-os",
3
- "version": "1.7.1",
3
+ "version": "1.8.1",
4
4
  "description": "Multi-agent skill package cho AI coding agents (Claude, Cursor, Windsurf, Antigravity) với 23 skills chuyên nghiệp.",
5
5
  "main": "bin/install.js",
6
6
  "bin": {