ai-developer-skill-os 7.0.2 → 7.5.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.
Files changed (206) hide show
  1. package/.agents/AGENTS.md +44 -88
  2. package/.agents/CHANGELOG.md +70 -0
  3. package/.agents/LICENSE +21 -0
  4. package/.agents/README.md +100 -0
  5. package/.agents/docs/CHI_TIET_SKILLS.md +126 -0
  6. package/.agents/docs/GOVERNANCE.md +40 -0
  7. package/.agents/docs/HUONG_DAN_SU_DUNG.md +120 -0
  8. package/.agents/docs/SPEC.md +87 -0
  9. package/.agents/docs/adr/0001-intent-based-architecture.md +19 -0
  10. package/.agents/docs/adr/0002-kernel-freeze.md +21 -0
  11. package/.agents/docs/adr/0003-risk-based-verification.md +20 -0
  12. package/.agents/docs/adr/0004-progressive-evidence.md +19 -0
  13. package/.agents/docs/skill-classification.md +25 -0
  14. package/.agents/skills/qk-access-policy/SKILL.md +179 -0
  15. package/.agents/skills/qk-ai-builder/SKILL.md +215 -0
  16. package/.agents/skills/qk-api-lifecycle/SKILL.md +176 -0
  17. package/.agents/skills/qk-bug-resolution/SKILL.md +307 -0
  18. package/.agents/skills/qk-context-loader/SKILL.md +218 -0
  19. package/.agents/skills/qk-data-lifecycle/SKILL.md +192 -0
  20. package/.agents/skills/qk-db-optimizer/SKILL.md +196 -0
  21. package/.agents/skills/qk-docs/SKILL.md +198 -0
  22. package/.agents/skills/qk-engineering-standard/SKILL.md +351 -0
  23. package/.agents/skills/qk-engineering-standard/rules/backend.md +122 -0
  24. package/.agents/skills/qk-engineering-standard/rules/database.md +3 -0
  25. package/.agents/skills/qk-engineering-standard/rules/frontend.md +152 -0
  26. package/.agents/skills/qk-engineering-standard/rules/security.md +3 -0
  27. package/.agents/skills/qk-engineering-standard/rules/testing.md +3 -0
  28. package/.agents/skills/qk-fe-api-integration/SKILL.md +326 -0
  29. package/.agents/skills/qk-feature-delivery/SKILL.md +305 -0
  30. package/.agents/skills/qk-help/SKILL.md +193 -0
  31. package/.agents/skills/qk-orchestrator/SKILL.md +278 -0
  32. package/.agents/skills/qk-orchestrator/references/routing-table.md +78 -0
  33. package/.agents/skills/qk-production-release/SKILL.md +284 -0
  34. package/.agents/skills/qk-project-bootstrap/SKILL.md +235 -0
  35. package/.agents/skills/qk-project-health/SKILL.md +199 -0
  36. package/.agents/skills/qk-project-memory/SKILL.md +218 -0
  37. package/.agents/skills/qk-system-evolution/SKILL.md +281 -0
  38. package/.agents/skills/qk-ui-audit/SKILL.md +315 -0
  39. package/.agents/skills/qk-ui-audit/references/anti-slop-checklist.md +136 -0
  40. package/.agents/skills/qk-ui-builder/SKILL.md +446 -0
  41. package/.agents/skills/qk-ui-builder/references/anti-patterns.md +295 -0
  42. package/.agents/skills/qk-ui-builder/references/color.md +115 -0
  43. package/.agents/skills/qk-ui-builder/references/component-cookbook.md +1194 -0
  44. package/.agents/skills/qk-ui-builder/references/copy.md +250 -0
  45. package/.agents/skills/qk-ui-builder/references/interaction-and-states.md +115 -0
  46. package/.agents/skills/qk-ui-builder/references/layout-and-space.md +111 -0
  47. package/.agents/skills/qk-ui-builder/references/macrostructures/01-bento-grid.md +48 -0
  48. package/.agents/skills/qk-ui-builder/references/macrostructures/02-long-document.md +50 -0
  49. package/.agents/skills/qk-ui-builder/references/macrostructures/03-marquee-hero.md +51 -0
  50. package/.agents/skills/qk-ui-builder/references/macrostructures/04-stat-led.md +49 -0
  51. package/.agents/skills/qk-ui-builder/references/macrostructures/05-workbench.md +44 -0
  52. package/.agents/skills/qk-ui-builder/references/macrostructures/06-conversational-faq.md +50 -0
  53. package/.agents/skills/qk-ui-builder/references/macrostructures/07-manifesto.md +51 -0
  54. package/.agents/skills/qk-ui-builder/references/macrostructures/08-photographic.md +50 -0
  55. package/.agents/skills/qk-ui-builder/references/macrostructures/09-quote-led.md +50 -0
  56. package/.agents/skills/qk-ui-builder/references/macrostructures/11-catalogue.md +49 -0
  57. package/.agents/skills/qk-ui-builder/references/macrostructures/12-letter.md +49 -0
  58. package/.agents/skills/qk-ui-builder/references/macrostructures/13-index-first.md +49 -0
  59. package/.agents/skills/qk-ui-builder/references/macrostructures/14-narrative-workflow.md +48 -0
  60. package/.agents/skills/qk-ui-builder/references/macrostructures/15-split-studio.md +48 -0
  61. package/.agents/skills/qk-ui-builder/references/macrostructures/16-feature-stack.md +51 -0
  62. package/.agents/skills/qk-ui-builder/references/macrostructures/17-type-specimen.md +48 -0
  63. package/.agents/skills/qk-ui-builder/references/macrostructures/18-portfolio-grid.md +48 -0
  64. package/.agents/skills/qk-ui-builder/references/macrostructures/19-map-diagram.md +50 -0
  65. package/.agents/skills/qk-ui-builder/references/macrostructures/20-ecosystem-index.md +48 -0
  66. package/.agents/skills/qk-ui-builder/references/macrostructures/21-component-playground.md +45 -0
  67. package/.agents/skills/qk-ui-builder/references/macrostructures.md +38 -0
  68. package/.agents/skills/qk-ui-builder/references/motion.md +95 -0
  69. package/.agents/skills/qk-ui-builder/references/responsive.md +115 -0
  70. package/.agents/skills/qk-ui-builder/references/slop-test.md +135 -0
  71. package/.agents/skills/qk-ui-builder/references/structure.md +280 -0
  72. package/.agents/skills/qk-ui-builder/references/themes/atmospheric.md +53 -0
  73. package/.agents/skills/qk-ui-builder/references/themes/carnival.md +52 -0
  74. package/.agents/skills/qk-ui-builder/references/themes/cobalt.md +52 -0
  75. package/.agents/skills/qk-ui-builder/references/themes/editorial.md +52 -0
  76. package/.agents/skills/qk-ui-builder/references/themes/garden.md +52 -0
  77. package/.agents/skills/qk-ui-builder/references/themes/hum.md +52 -0
  78. package/.agents/skills/qk-ui-builder/references/themes/lumen.md +52 -0
  79. package/.agents/skills/qk-ui-builder/references/themes/midnight.md +52 -0
  80. package/.agents/skills/qk-ui-builder/references/themes/modern-minimal.md +52 -0
  81. package/.agents/skills/qk-ui-builder/references/themes/playful.md +52 -0
  82. package/.agents/skills/qk-ui-builder/references/themes/specimen.md +52 -0
  83. package/.agents/skills/qk-ui-builder/references/themes/terminal.md +52 -0
  84. package/.agents/skills/qk-ui-builder/references/typography.md +129 -0
  85. package/.agents/skills/qk-ui-system-builder/SKILL.md +221 -0
  86. package/.agents/skills/qk-validation-gate/SKILL.md +359 -0
  87. package/.agents/skills.json +819 -0
  88. package/.github/workflows/ci.yml +1 -1
  89. package/CHANGELOG.md +2 -1
  90. package/CLAUDE.md +110 -0
  91. package/README.md +52 -10
  92. package/add_lang.js +21 -0
  93. package/add_lang.py +25 -0
  94. package/add_sections.py +53 -0
  95. package/bin/install.js +225 -170
  96. package/bin/lint.js +123 -0
  97. package/docs/CHI_TIET_SKILLS.md +27 -26
  98. package/docs/HUONG_DAN_SU_DUNG.md +3 -3
  99. package/docs/SPEC.md +70 -20
  100. package/framework/decision-primitives.md +2 -1
  101. package/framework/skill-schema.md +310 -0
  102. package/package.json +16 -5
  103. package/patch.js +15 -0
  104. package/patch.py +89 -0
  105. package/patch2.py +83 -0
  106. package/skills/_archive_old_skills/qk-accessibility-audit/SKILL.md +1 -0
  107. package/skills/_archive_old_skills/qk-agent-orchestrator/SKILL.md +1 -0
  108. package/skills/_archive_old_skills/qk-api-integration/SKILL.md +1 -0
  109. package/skills/_archive_old_skills/qk-auth-security/SKILL.md +1 -0
  110. package/skills/_archive_old_skills/qk-backend-architecture/SKILL.md +1 -0
  111. package/skills/_archive_old_skills/qk-bug-fix/SKILL.md +1 -0
  112. package/skills/_archive_old_skills/qk-component-generator/SKILL.md +1 -0
  113. package/skills/_archive_old_skills/qk-context-manager/SKILL.md +1 -0
  114. package/skills/_archive_old_skills/qk-database-engineer/SKILL.md +1 -0
  115. package/skills/_archive_old_skills/qk-deployment/SKILL.md +1 -0
  116. package/skills/_archive_old_skills/qk-design-system/SKILL.md +1 -0
  117. package/skills/_archive_old_skills/qk-form-builder/SKILL.md +1 -0
  118. package/skills/_archive_old_skills/qk-frontend-architecture/SKILL.md +1 -0
  119. package/skills/_archive_old_skills/qk-frontend-debug/SKILL.md +1 -0
  120. package/skills/_archive_old_skills/qk-frontend-performance/SKILL.md +1 -0
  121. package/skills/_archive_old_skills/qk-frontend-testing/SKILL.md +1 -0
  122. package/skills/_archive_old_skills/qk-git-engineer/SKILL.md +1 -0
  123. package/skills/_archive_old_skills/qk-help/SKILL.md +1 -0
  124. package/skills/_archive_old_skills/qk-migration/SKILL.md +1 -0
  125. package/skills/_archive_old_skills/qk-project-audit/SKILL.md +1 -0
  126. package/skills/_archive_old_skills/qk-refactor/SKILL.md +1 -0
  127. package/skills/_archive_old_skills/qk-state-management/SKILL.md +1 -0
  128. package/skills/_archive_old_skills/qk-table-crud-generator/SKILL.md +1 -0
  129. package/skills/_archive_old_skills/qk-ui-builder/SKILL.md +1 -0
  130. package/skills/_template/SKILL.md +239 -0
  131. package/skills/qk-access-policy/SKILL.md +180 -39
  132. package/skills/qk-ai-builder/SKILL.md +216 -40
  133. package/skills/qk-api-lifecycle/SKILL.md +177 -46
  134. package/skills/qk-bug-resolution/SKILL.md +308 -46
  135. package/skills/qk-context-loader/SKILL.md +219 -43
  136. package/skills/qk-data-lifecycle/SKILL.md +193 -44
  137. package/skills/qk-db-optimizer/SKILL.md +197 -41
  138. package/skills/qk-docs/SKILL.md +199 -40
  139. package/skills/qk-engineering-standard/SKILL.md +352 -42
  140. package/skills/qk-fe-api-integration/SKILL.md +327 -55
  141. package/skills/qk-feature-delivery/SKILL.md +306 -48
  142. package/skills/qk-help/SKILL.md +179 -23
  143. package/skills/qk-orchestrator/SKILL.md +279 -42
  144. package/skills/qk-orchestrator/references/routing-table.md +78 -0
  145. package/skills/qk-production-release/SKILL.md +285 -41
  146. package/skills/qk-project-bootstrap/SKILL.md +236 -38
  147. package/skills/qk-project-health/SKILL.md +200 -40
  148. package/skills/qk-project-memory/SKILL.md +219 -40
  149. package/skills/qk-system-evolution/SKILL.md +282 -40
  150. package/skills/qk-ui-audit/SKILL.md +316 -42
  151. package/skills/qk-ui-audit/references/anti-slop-checklist.md +136 -0
  152. package/skills/qk-ui-builder/SKILL.md +447 -0
  153. package/skills/qk-ui-builder/references/anti-patterns.md +295 -0
  154. package/skills/qk-ui-builder/references/color.md +115 -0
  155. package/skills/qk-ui-builder/references/component-cookbook.md +1194 -0
  156. package/skills/qk-ui-builder/references/copy.md +250 -0
  157. package/skills/qk-ui-builder/references/interaction-and-states.md +115 -0
  158. package/skills/qk-ui-builder/references/layout-and-space.md +111 -0
  159. package/skills/qk-ui-builder/references/macrostructures/01-bento-grid.md +48 -0
  160. package/skills/qk-ui-builder/references/macrostructures/02-long-document.md +50 -0
  161. package/skills/qk-ui-builder/references/macrostructures/03-marquee-hero.md +51 -0
  162. package/skills/qk-ui-builder/references/macrostructures/04-stat-led.md +49 -0
  163. package/skills/qk-ui-builder/references/macrostructures/05-workbench.md +44 -0
  164. package/skills/qk-ui-builder/references/macrostructures/06-conversational-faq.md +50 -0
  165. package/skills/qk-ui-builder/references/macrostructures/07-manifesto.md +51 -0
  166. package/skills/qk-ui-builder/references/macrostructures/08-photographic.md +50 -0
  167. package/skills/qk-ui-builder/references/macrostructures/09-quote-led.md +50 -0
  168. package/skills/qk-ui-builder/references/macrostructures/11-catalogue.md +49 -0
  169. package/skills/qk-ui-builder/references/macrostructures/12-letter.md +49 -0
  170. package/skills/qk-ui-builder/references/macrostructures/13-index-first.md +49 -0
  171. package/skills/qk-ui-builder/references/macrostructures/14-narrative-workflow.md +48 -0
  172. package/skills/qk-ui-builder/references/macrostructures/15-split-studio.md +48 -0
  173. package/skills/qk-ui-builder/references/macrostructures/16-feature-stack.md +51 -0
  174. package/skills/qk-ui-builder/references/macrostructures/17-type-specimen.md +48 -0
  175. package/skills/qk-ui-builder/references/macrostructures/18-portfolio-grid.md +48 -0
  176. package/skills/qk-ui-builder/references/macrostructures/19-map-diagram.md +50 -0
  177. package/skills/qk-ui-builder/references/macrostructures/20-ecosystem-index.md +48 -0
  178. package/skills/qk-ui-builder/references/macrostructures/21-component-playground.md +45 -0
  179. package/skills/qk-ui-builder/references/macrostructures.md +38 -0
  180. package/skills/qk-ui-builder/references/motion.md +95 -0
  181. package/skills/qk-ui-builder/references/responsive.md +115 -0
  182. package/skills/qk-ui-builder/references/slop-test.md +135 -0
  183. package/skills/qk-ui-builder/references/structure.md +280 -0
  184. package/skills/qk-ui-builder/references/themes/atmospheric.md +53 -0
  185. package/skills/qk-ui-builder/references/themes/carnival.md +52 -0
  186. package/skills/qk-ui-builder/references/themes/cobalt.md +52 -0
  187. package/skills/qk-ui-builder/references/themes/editorial.md +52 -0
  188. package/skills/qk-ui-builder/references/themes/garden.md +52 -0
  189. package/skills/qk-ui-builder/references/themes/hum.md +52 -0
  190. package/skills/qk-ui-builder/references/themes/lumen.md +52 -0
  191. package/skills/qk-ui-builder/references/themes/midnight.md +52 -0
  192. package/skills/qk-ui-builder/references/themes/modern-minimal.md +52 -0
  193. package/skills/qk-ui-builder/references/themes/playful.md +52 -0
  194. package/skills/qk-ui-builder/references/themes/specimen.md +52 -0
  195. package/skills/qk-ui-builder/references/themes/terminal.md +52 -0
  196. package/skills/qk-ui-builder/references/typography.md +129 -0
  197. package/skills/qk-ui-system-builder/SKILL.md +222 -43
  198. package/skills/qk-validation-gate/SKILL.md +360 -40
  199. package/skills.json +815 -825
  200. package/specs/fixtures/user-payload.json +12 -0
  201. package/specs/regressions/api-integration-null-fields.yaml +19 -0
  202. package/temp_fix.js +61 -0
  203. package/tests/registry.test.js +1 -1
  204. package/update_template.js +28 -0
  205. package/skills/qk-design-to-code/SKILL.md +0 -46
  206. package/skills/qk-policy-engine/SKILL.md +0 -39
package/bin/install.js CHANGED
@@ -15,8 +15,13 @@ function copyRecursiveSync(src, dest) {
15
15
  const exists = fs.existsSync(src);
16
16
  const stats = exists && fs.statSync(src);
17
17
  const isDirectory = exists && stats.isDirectory();
18
-
18
+
19
19
  if (isDirectory) {
20
+ const dirName = path.basename(src);
21
+ if (dirName.startsWith('_')) {
22
+ return;
23
+ }
24
+
20
25
  if (!fs.existsSync(dest)) {
21
26
  fs.mkdirSync(dest, { recursive: true });
22
27
  }
@@ -69,7 +74,7 @@ function ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloComman
69
74
  }
70
75
 
71
76
  const skillPaths = [kiloSkillsDir];
72
- if (!Array.isArray(kiloConfig.skills) || typeof kiloConfig.skills !== 'object' || !kiloConfig.skills.paths) {
77
+ if (!kiloConfig.skills || typeof kiloConfig.skills !== 'object' || !Array.isArray(kiloConfig.skills.paths)) {
73
78
  kiloConfig.skills = { paths: skillPaths };
74
79
  } else {
75
80
  const exists = kiloConfig.skills.paths.some(p => path.resolve(p) === path.resolve(kiloSkillsDir));
@@ -82,38 +87,53 @@ function ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloComman
82
87
  return kiloJsonPath;
83
88
  }
84
89
 
85
- const rl = readline.createInterface({
86
- input: process.stdin,
87
- output: process.stdout
88
- });
89
-
90
- console.log('🚀 Đang chuẩn bị cài đặt AI Developer Skill OS...\n');
91
-
92
- const questionIde = `Vui lòng chọn IDE/AI Assistant bạn đang sử dụng:
93
- (1) Cursor
94
- (2) Windsurf
95
- (3) Cline / Roo Code
96
- (4) Antigravity / Gemini
97
- (5) Codex
98
- (6) Kilo Code
99
- (7) Tất cả các IDE (Multi-IDE)
100
- (0) Bỏ qua (Không tạo config tự động)
90
+ function parseArgs() {
91
+ const args = process.argv.slice(2);
92
+ const parsed = { ide: null, scope: null };
93
+ for (const arg of args) {
94
+ if (arg.startsWith('--ide=')) parsed.ide = arg.split('=')[1];
95
+ if (arg.startsWith('--scope=')) parsed.scope = arg.split('=')[1];
96
+ }
101
97
 
102
- Nhập số (0-7): `;
98
+ const aliasMap = {
99
+ 'antigravity': '4',
100
+ 'gemini': '4',
101
+ 'cursor': '1',
102
+ 'windsurf': '2',
103
+ 'claude': '3',
104
+ 'cliner': '3',
105
+ 'roo': '3',
106
+ 'codex': '5',
107
+ 'kilo': '6',
108
+ 'multi-ide': '7',
109
+ 'all': '7'
110
+ };
111
+
112
+ if (parsed.ide && aliasMap[parsed.ide.toLowerCase()]) {
113
+ parsed.ide = aliasMap[parsed.ide.toLowerCase()];
114
+ }
103
115
 
104
- const questionScope = `
105
- Bạn muốn cài đặt bộ kỹ năng ở đâu?
106
- (1) Local (Gắn vào dự án hiện tại - Phù hợp làm việc nhóm)
107
- (2) Global (Cài vào máy tính dùng chung cho mọi dự án - Dành cho cá nhân)
116
+ if (args.includes('--antigravity')) {
117
+ parsed.ide = '4';
118
+ if (!parsed.scope) parsed.scope = '2';
119
+ }
120
+ if (args.includes('--cursor')) {
121
+ parsed.ide = '1';
122
+ if (!parsed.scope) parsed.scope = '2';
123
+ }
124
+ if (args.includes('--kilo')) {
125
+ parsed.ide = '6';
126
+ if (!parsed.scope) parsed.scope = '2';
127
+ }
108
128
 
109
- Nhập số (1-2): `;
129
+ return parsed;
130
+ }
110
131
 
111
- rl.question(questionIde, (answerIde) => {
132
+ function runInstall(ideCode, answerScope) {
112
133
  let isGemini = false;
113
134
  let isKilo = false;
114
135
  let isMultiIde = false;
115
136
  let ruleFileName = null;
116
- const ideCode = answerIde.trim();
117
137
 
118
138
  switch(ideCode) {
119
139
  case '1': ruleFileName = '.cursorrules'; break;
@@ -126,70 +146,69 @@ rl.question(questionIde, (answerIde) => {
126
146
  case '0': default: break;
127
147
  }
128
148
 
129
- rl.question(questionScope, (answerScope) => {
130
- const isGlobal = answerScope.trim() === '2';
131
-
132
- const homeDir = os.homedir();
133
- const cwd = process.cwd();
134
- let targetDir = '';
135
- let ruleFilePath = null;
136
- let baseFolderForPrompt = '';
137
- let kiloJsonPath = null;
138
- let kiloSkillsDir = null;
139
- let kiloThemesDir = null;
140
- let kiloCommandsDir = null;
141
-
142
- if (isMultiIde) {
149
+ const isGlobal = answerScope.trim() === '2';
150
+
151
+ const homeDir = os.homedir();
152
+ const cwd = process.cwd();
153
+ let targetDir = '';
154
+ let ruleFilePath = null;
155
+ let baseFolderForPrompt = '';
156
+ let kiloJsonPath = null;
157
+ let kiloSkillsDir = null;
158
+ let kiloThemesDir = null;
159
+ let kiloCommandsDir = null;
160
+
161
+ if (isMultiIde) {
162
+ targetDir = path.join(cwd, '.qk-ai-skill-os');
163
+ baseFolderForPrompt = './.qk-ai-skill-os';
164
+ ruleFilePath = path.join(cwd, 'CLAUDE.md');
165
+ if (!isGlobal) {
166
+ kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
167
+ kiloThemesDir = path.join(cwd, '.kilo', 'themes');
168
+ kiloCommandsDir = path.join(cwd, '.kilo', 'command');
169
+ kiloJsonPath = path.join(cwd, 'kilo.json');
170
+ }
171
+ } else if (isGemini) {
172
+ if (isGlobal) {
173
+ targetDir = path.join(homeDir, '.gemini', 'config');
174
+ ruleFilePath = path.join(targetDir, 'AGENTS.md');
175
+ baseFolderForPrompt = path.join(targetDir, 'skills').replace(/\\/g, '/');
176
+ } else {
177
+ targetDir = path.join(cwd, '.agents');
178
+ ruleFilePath = path.join(cwd, '.agents', 'AGENTS.md');
179
+ baseFolderForPrompt = '.agents/skills';
180
+ }
181
+ } else if (isKilo) {
182
+ if (isGlobal) {
183
+ targetDir = path.join(homeDir, '.qk-ai-skill-os');
184
+ baseFolderForPrompt = targetDir.replace(/\\/g, '/');
185
+ kiloSkillsDir = path.join(homeDir, '.kilo', 'skills');
186
+ kiloThemesDir = path.join(homeDir, '.config', 'kilo', 'themes');
187
+ kiloCommandsDir = path.join(homeDir, '.config', 'kilo', 'command');
188
+ kiloJsonPath = path.join(homeDir, '.config', 'kilo', 'kilo.json');
189
+ } else {
143
190
  targetDir = path.join(cwd, '.qk-ai-skill-os');
144
191
  baseFolderForPrompt = './.qk-ai-skill-os';
145
- ruleFilePath = path.join(cwd, 'CLAUDE.md');
146
- if (!isGlobal) {
147
- kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
148
- kiloThemesDir = path.join(cwd, '.kilo', 'themes');
149
- kiloCommandsDir = path.join(cwd, '.kilo', 'command');
150
- kiloJsonPath = path.join(cwd, 'kilo.json');
151
- }
152
- } else if (isGemini) {
153
- if (isGlobal) {
154
- targetDir = path.join(homeDir, '.gemini', 'config');
155
- ruleFilePath = path.join(targetDir, 'AGENTS.md');
156
- baseFolderForPrompt = path.join(targetDir, 'skills').replace(/\\/g, '/');
157
- } else {
158
- targetDir = path.join(cwd, '.agents');
159
- ruleFilePath = path.join(cwd, '.agents', 'AGENTS.md');
160
- baseFolderForPrompt = '.agents/skills';
161
- }
162
- } else if (isKilo) {
163
- if (isGlobal) {
164
- targetDir = path.join(homeDir, '.qk-ai-skill-os');
165
- baseFolderForPrompt = targetDir.replace(/\\/g, '/');
166
- kiloSkillsDir = path.join(homeDir, '.kilo', 'skills');
167
- kiloThemesDir = path.join(homeDir, '.config', 'kilo', 'themes');
168
- kiloCommandsDir = path.join(homeDir, '.config', 'kilo', 'command');
169
- kiloJsonPath = path.join(homeDir, '.config', 'kilo', 'kilo.json');
170
- } else {
171
- targetDir = path.join(cwd, '.qk-ai-skill-os');
172
- baseFolderForPrompt = './.qk-ai-skill-os';
173
- kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
174
- kiloThemesDir = path.join(cwd, '.kilo', 'themes');
175
- kiloCommandsDir = path.join(cwd, '.kilo', 'command');
176
- kiloJsonPath = path.join(cwd, 'kilo.json');
177
- }
178
- ruleFilePath = path.join(cwd, 'CLAUDE.md');
192
+ kiloSkillsDir = path.join(cwd, '.kilo', 'skills');
193
+ kiloThemesDir = path.join(cwd, '.kilo', 'themes');
194
+ kiloCommandsDir = path.join(cwd, '.kilo', 'command');
195
+ kiloJsonPath = path.join(cwd, 'kilo.json');
196
+ }
197
+ ruleFilePath = path.join(cwd, 'CLAUDE.md');
198
+ } else {
199
+ if (isGlobal) {
200
+ targetDir = path.join(homeDir, '.qk-ai-skill-os');
201
+ baseFolderForPrompt = targetDir.replace(/\\/g, '/');
179
202
  } else {
180
- if (isGlobal) {
181
- targetDir = path.join(homeDir, '.qk-ai-skill-os');
182
- baseFolderForPrompt = targetDir.replace(/\\/g, '/');
183
- } else {
184
- targetDir = path.join(cwd, '.qk-ai-skill-os');
185
- baseFolderForPrompt = './.qk-ai-skill-os';
186
- }
187
- if (ruleFileName) {
188
- ruleFilePath = path.join(cwd, ruleFileName);
189
- }
203
+ targetDir = path.join(cwd, '.qk-ai-skill-os');
204
+ baseFolderForPrompt = './.qk-ai-skill-os';
205
+ }
206
+ if (ruleFileName) {
207
+ ruleFilePath = path.join(cwd, ruleFileName);
190
208
  }
209
+ }
191
210
 
192
- const systemPrompt = `[Role]
211
+ const systemPrompt = `[Role]
193
212
  You are an elite AI Software Engineer. You must strictly follow the rules in this project.
194
213
  Vui lòng tìm đọc danh sách kỹ năng tại file \`${baseFolderForPrompt}/skills.json\`.
195
214
 
@@ -202,7 +221,7 @@ Khi nhận được lệnh kỹ năng, bạn BẮT BUỘC phải:
202
221
  2. TỰ ĐỘNG THỰC THI (End-to-End): Dùng các tools của bạn (đọc file, sửa code, chạy lệnh) để tự động hoàn thành 100% mục tiêu được giao. KHÔNG ĐƯỢC dừng lại để hỏi ý kiến trừ khi gặp lỗi chí mạng hoặc requirement quá mập mờ.
203
222
  3. BÁO CÁO KẾT QUẢ: Sau khi hoàn tất sửa code, LUÔN trả về báo cáo theo đúng format markdown dưới đây:
204
223
 
205
- \\\`\\\`\\\`markdown
224
+ \`\`\`markdown
206
225
  🔧 <Tên Kỹ Năng> Summary
207
226
  ─────────────────────────────────────────────────
208
227
  Scope: [Tóm tắt ngắn gọn phạm vi công việc]
@@ -223,114 +242,150 @@ Changes applied:
223
242
 
224
243
  ⚠️ Notes:
225
244
  [Các lưu ý đặc biệt, rủi ro tiềm ẩn hoặc cách người dùng có thể test lại tính năng này]
226
- \\\`\\\`\\\`
245
+ \`\`\`
227
246
 
228
247
  [Command Arguments]
229
- Người dùng có thể truyền thêm tham số vào lệnh (ví dụ: \`./qk-ui-builder --fw=react --css=tailwind\`).
248
+ Người dùng có thể truyền thêm tham số vào lệnh (ví dụ: \`./qk-ui-builder --fw=react --css=tailwind\`).
230
249
  Nếu người dùng sử dụng tham số (argument), bạn BẮT BUỘC phải tuân thủ tuyệt đối các công nghệ/yêu cầu được chỉ định trong tham số đó thay vì dùng mặc định.`;
231
250
 
232
- try {
233
- if (!fs.existsSync(targetDir)) {
234
- fs.mkdirSync(targetDir, { recursive: true });
235
- }
251
+ try {
252
+ if (!fs.existsSync(targetDir)) {
253
+ fs.mkdirSync(targetDir, { recursive: true });
254
+ }
236
255
 
237
- const targetSkillsDir = path.join(targetDir, 'skills');
238
- cleanOldSkills(targetSkillsDir, isGemini && isGlobal);
256
+ const targetSkillsDir = path.join(targetDir, 'skills');
257
+ cleanOldSkills(targetSkillsDir, isGemini && isGlobal);
239
258
 
240
- const filesAndFolders = [
241
- 'skills', '_template', 'docs', 'skills.json', 'README.md', 'CHANGELOG.md', 'LICENSE'
242
- ];
259
+ const filesAndFolders = [
260
+ 'skills', '_template', 'docs', 'skills.json', 'README.md', 'CHANGELOG.md', 'LICENSE'
261
+ ];
243
262
 
244
- if (isGemini && isGlobal) {
245
- if (fs.existsSync(path.join(sourceDir, 'skills'))) {
246
- copyRecursiveSync(path.join(sourceDir, 'skills'), path.join(targetDir, 'skills'));
247
- }
248
- if (fs.existsSync(path.join(sourceDir, 'skills.json'))) {
249
- fs.copyFileSync(path.join(sourceDir, 'skills.json'), path.join(targetDir, 'skills', 'skills.json'));
250
- }
251
- } else {
252
- filesAndFolders.forEach(item => {
253
- const src = path.join(sourceDir, item);
254
- let dest = path.join(targetDir, item);
255
- if (fs.existsSync(src)) {
256
- copyRecursiveSync(src, dest);
257
- }
258
- });
263
+ if (isGemini && isGlobal) {
264
+ if (fs.existsSync(path.join(sourceDir, 'skills'))) {
265
+ copyRecursiveSync(path.join(sourceDir, 'skills'), path.join(targetDir, 'skills'));
259
266
  }
260
-
261
- if (ruleFilePath) {
262
- const ruleDir = path.dirname(ruleFilePath);
263
- if (ruleDir !== cwd && !fs.existsSync(ruleDir)) {
264
- fs.mkdirSync(ruleDir, { recursive: true });
267
+ if (fs.existsSync(path.join(sourceDir, 'skills.json'))) {
268
+ fs.copyFileSync(path.join(sourceDir, 'skills.json'), path.join(targetDir, 'skills', 'skills.json'));
269
+ }
270
+ } else {
271
+ filesAndFolders.forEach(item => {
272
+ const src = path.join(sourceDir, item);
273
+ let dest = path.join(targetDir, item);
274
+ if (fs.existsSync(src)) {
275
+ copyRecursiveSync(src, dest);
265
276
  }
277
+ });
278
+ }
266
279
 
267
- let writeContent = systemPrompt;
268
- if (isGemini) {
269
- writeContent = `\n<RULE[ai_skill_os]>\n---\ntrigger: always_on\n---\n${systemPrompt}\n</RULE[ai_skill_os]>\n`;
270
- }
280
+ if (ruleFilePath) {
281
+ const ruleDir = path.dirname(ruleFilePath);
282
+ if (ruleDir !== cwd && !fs.existsSync(ruleDir)) {
283
+ fs.mkdirSync(ruleDir, { recursive: true });
284
+ }
285
+
286
+ let writeContent = systemPrompt;
287
+ if (isGemini) {
288
+ writeContent = `\n<RULE[ai_skill_os]>\n---\ntrigger: always_on\n---\n${systemPrompt}\n</RULE[ai_skill_os]>\n`;
289
+ }
271
290
 
272
- if (fs.existsSync(ruleFilePath)) {
273
- const existingContent = fs.readFileSync(ruleFilePath, 'utf8');
274
- const marker = isGemini ? '<RULE[ai_skill_os]>' : '[Role]\nYou are an elite AI Software Engineer.';
275
- const markerIndex = existingContent.indexOf(marker);
276
- if (markerIndex !== -1) {
277
- const before = existingContent.substring(0, markerIndex);
278
- const after = existingContent.substring(markerIndex).split('\n').slice(isGemini ? 2 : 1).join('\n');
279
- const lastMarkerEnd = after.indexOf(isGemini ? '</RULE[ai_skill_os]>' : '[Trigger Mechanism]');
280
- const actualAfter = lastMarkerEnd !== -1 ? after.substring(lastMarkerEnd + (isGemini ? 19 : 18)).trimStart() : after;
281
- fs.writeFileSync(ruleFilePath, before + writeContent.trimStart() + (actualAfter ? '\n' + actualAfter : '') + '\n');
282
- console.log(`✅ Đã CẬP NHẬT cấu hình tự động trong file: ${ruleFilePath}`);
283
- } else {
284
- fs.appendFileSync(ruleFilePath, "\n\n" + writeContent);
285
- console.log(`✅ Đã GHI THÊM cấu hình tự động vào file: ${ruleFilePath}`);
286
- }
291
+ if (fs.existsSync(ruleFilePath)) {
292
+ const existingContent = fs.readFileSync(ruleFilePath, 'utf8');
293
+ const marker = isGemini ? '<RULE[ai_skill_os]>' : '[Role]\nYou are an elite AI Software Engineer.';
294
+ const markerIndex = existingContent.indexOf(marker);
295
+ if (markerIndex !== -1) {
296
+ const before = existingContent.substring(0, markerIndex);
297
+ const after = existingContent.substring(markerIndex).split('\n').slice(isGemini ? 2 : 1).join('\n');
298
+ const lastMarkerEnd = after.indexOf(isGemini ? '</RULE[ai_skill_os]>' : '[Trigger Mechanism]');
299
+ const actualAfter = lastMarkerEnd !== -1 ? after.substring(lastMarkerEnd + (isGemini ? 19 : 18)).trimStart() : after;
300
+ fs.writeFileSync(ruleFilePath, before + writeContent.trimStart() + (actualAfter ? '\n' + actualAfter : '') + '\n');
301
+ console.log(`✅ Đã CẬP NHẬT cấu hình tự động trong file: ${ruleFilePath}`);
287
302
  } else {
288
- fs.writeFileSync(ruleFilePath, writeContent);
289
- console.log(`✅ Đã TẠO MỚI file cấu hình: ${ruleFilePath}`);
303
+ fs.appendFileSync(ruleFilePath, "\n\n" + writeContent);
304
+ console.log(`✅ Đã GHI THÊM cấu hình tự động vào file: ${ruleFilePath}`);
290
305
  }
306
+ } else {
307
+ fs.writeFileSync(ruleFilePath, writeContent);
308
+ console.log(`✅ Đã TẠO MỚI file cấu hình: ${ruleFilePath}`);
291
309
  }
310
+ }
292
311
 
293
- if (isKilo) {
312
+ if (isKilo) {
313
+ ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir);
314
+ console.log(`✅ Đã cấu hình Kilo Code tại: ${kiloJsonPath}`);
315
+ console.log(` → Skills: ${kiloSkillsDir}`);
316
+ console.log(` → Themes: ${kiloThemesDir}`);
317
+ console.log(` → Commands: ${kiloCommandsDir}`);
318
+ }
319
+
320
+ if (isMultiIde) {
321
+ if (kiloJsonPath && kiloSkillsDir) {
294
322
  ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir);
295
- console.log(`✅ Đã cấu hình Kilo Code tại: ${kiloJsonPath}`);
323
+ console.log(`✅ Đã cấu hình Kilo Code (Multi-IDE) tại: ${kiloJsonPath}`);
296
324
  console.log(` → Skills: ${kiloSkillsDir}`);
297
325
  console.log(` → Themes: ${kiloThemesDir}`);
298
326
  console.log(` → Commands: ${kiloCommandsDir}`);
327
+ } else if (ruleFilePath) {
328
+ console.log(`✅ Đã tạo file cấu hình Multi-IDE: ${ruleFilePath}`);
299
329
  }
330
+ }
300
331
 
301
- if (isMultiIde) {
302
- if (kiloJsonPath && kiloSkillsDir) {
303
- ensureKiloConfig(kiloJsonPath, kiloSkillsDir, kiloThemesDir, kiloCommandsDir);
304
- console.log(`✅ Đã cấu hình Kilo Code (Multi-IDE) tại: ${kiloJsonPath}`);
305
- console.log(` → Skills: ${kiloSkillsDir}`);
306
- console.log(` → Themes: ${kiloThemesDir}`);
307
- console.log(` → Commands: ${kiloCommandsDir}`);
308
- } else if (ruleFilePath) {
309
- console.log(`✅ Đã tạo file cấu hình Multi-IDE: ${ruleFilePath}`);
310
- }
311
- }
332
+ console.log(`\n🎉 HOÀN TẤT! Dữ liệu kỹ năng đã được lưu tại: ${targetDir}`);
333
+ if (isGlobal && !isGemini) {
334
+ const name = ruleFilePath ? path.basename(ruleFilePath) : 'CLAUDE.md';
335
+ 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 đó.`);
336
+ } else if (isGlobal && isGemini) {
337
+ 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ó đủ 22 kỹ năng mà không cần cài lại!`);
338
+ } else if (isKilo) {
339
+ 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.`);
340
+ }
312
341
 
313
- console.log(`\n🎉 HOÀN TẤT! Dữ liệu kỹ năng đã được lưu tại: ${targetDir}`);
314
- if (isGlobal && !isGemini) {
315
- const name = ruleFilePath ? path.basename(ruleFilePath) : 'CLAUDE.md';
316
- 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 đó.`);
317
- } else if (isGlobal && isGemini) {
318
- 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!`);
319
- } else if (isKilo) {
320
- 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.`);
342
+ if (!isGemini && !isKilo && !isMultiIde) {
343
+ if (fs.existsSync(path.join(cwd, '.kilorules'))) {
344
+ fs.unlinkSync(path.join(cwd, '.kilorules'));
345
+ console.log(`🧹 Đã xoá file .kilorules (không còn cần thiết).`);
321
346
  }
347
+ }
322
348
 
323
- if (!isGemini && !isKilo && !isMultiIde) {
324
- if (fs.existsSync(path.join(cwd, '.kilorules'))) {
325
- fs.unlinkSync(path.join(cwd, '.kilorules'));
326
- console.log(`🧹 Đã xoá file .kilorules cũ (không còn cần thiết).`);
327
- }
328
- }
349
+ } catch (error) {
350
+ console.error('❌ Có lỗi xảy ra trong quá trình cài đặt:', error.message);
351
+ }
352
+ }
329
353
 
330
- } catch (error) {
331
- console.error('❌ Có lỗi xảy ra trong quá trình cài đặt:', error.message);
332
- } finally {
354
+ const args = parseArgs();
355
+
356
+ if (args.ide !== null && args.scope !== null) {
357
+ runInstall(args.ide, args.scope);
358
+ } else {
359
+ console.log('🚀 Đang chuẩn bị cài đặt AI Developer Skill OS...\n');
360
+
361
+ const questionIde = `Vui lòng chọn IDE/AI Assistant bạn đang sử dụng:
362
+ (1) Cursor
363
+ (2) Windsurf
364
+ (3) Cline / Roo Code
365
+ (4) Antigravity / Gemini
366
+ (5) Codex
367
+ (6) Kilo Code
368
+ (7) Tất cả các IDE (Multi-IDE)
369
+ (0) Bỏ qua (Không tạo config tự động)
370
+
371
+ Nhập số (0-7): `;
372
+
373
+ const questionScope = `
374
+ Bạn muốn cài đặt bộ kỹ năng ở đâu?
375
+ (1) Local (Gắn vào dự án hiện tại - Phù hợp làm việc nhóm)
376
+ (2) Global (Cài vào máy tính dùng chung cho mọi dự án - Dành cho cá nhân)
377
+
378
+ Nhập số (1-2): `;
379
+
380
+ const rl = readline.createInterface({
381
+ input: process.stdin,
382
+ output: process.stdout
383
+ });
384
+
385
+ rl.question(questionIde, (answerIde) => {
386
+ rl.question(questionScope, (answerScope) => {
333
387
  rl.close();
334
- }
388
+ runInstall(answerIde.trim(), answerScope.trim());
389
+ });
335
390
  });
336
- });
391
+ }
package/bin/lint.js ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import matter from 'gray-matter';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ const skillsDir = path.join(__dirname, '..', 'skills');
11
+
12
+ const REQUIRED_FOR_ALL = [
13
+ 'Preconditions',
14
+ 'Scope',
15
+ 'Non-Goals',
16
+ 'Exit Codes',
17
+ 'Handoff Contract'
18
+ ];
19
+
20
+ const REQUIRED_FOR_ACTION = [
21
+ 'Workflow',
22
+ 'Confidence Model',
23
+ 'Evidence Format',
24
+ 'Escalation Rules'
25
+ ];
26
+
27
+ const REQUIRED_FOR_EXECUTION = [
28
+ 'Priority Order',
29
+ 'Severity',
30
+ 'Retry Policy'
31
+ ];
32
+
33
+ const ACTION_SKILLS = ['qk-bug-resolution', 'qk-feature-delivery', 'qk-fe-api-integration', 'qk-api-lifecycle', 'qk-data-lifecycle', 'qk-db-optimizer', 'qk-ui-builder', 'qk-ui-system-builder', 'qk-access-policy', 'qk-ai-builder', 'qk-system-evolution', 'qk-production-release', 'qk-project-bootstrap'];
34
+ const EXECUTION_SKILLS = ['qk-bug-resolution', 'qk-feature-delivery', 'qk-fe-api-integration', 'qk-api-lifecycle', 'qk-data-lifecycle', 'qk-db-optimizer', 'qk-ui-builder', 'qk-ui-system-builder', 'qk-access-policy', 'qk-ai-builder', 'qk-system-evolution', 'qk-production-release', 'qk-project-bootstrap', 'qk-engineering-standard', 'qk-validation-gate', 'qk-ui-audit', 'qk-project-health'];
35
+
36
+ const SKIP_LINT = ['qk-help'];
37
+
38
+ let hasErrors = false;
39
+
40
+ function lintSkill(skillPath, skillName) {
41
+ if (SKIP_LINT.includes(skillName)) {
42
+ console.log(`⏭️ [${skillName}] Skipped (reference skill)`);
43
+ return;
44
+ }
45
+
46
+ const content = fs.readFileSync(skillPath, 'utf8');
47
+
48
+ let parsed;
49
+ try {
50
+ parsed = matter(content);
51
+ } catch (e) {
52
+ console.error(`❌ [${skillName}] Frontmatter parsing failed: ${e.message}`);
53
+ hasErrors = true;
54
+ return;
55
+ }
56
+
57
+ const frontmatter = parsed.data;
58
+
59
+ const requiredFrontmatter = ['name', 'category', 'version', 'description', 'platforms', 'execution_mode', 'cost', 'latency', 'risk', 'side_effects', 'produces', 'consumes', 'token_budget', 'exit_codes', 'schema_version', 'runtime_version', 'skill_version'];
60
+
61
+ for (const field of requiredFrontmatter) {
62
+ if (frontmatter[field] === undefined) {
63
+ console.error(`❌ [${skillName}] Missing frontmatter field: ${field}`);
64
+ hasErrors = true;
65
+ }
66
+ }
67
+
68
+ const validPlatforms = ['antigravity', 'claude-code', 'cursor', 'windsurf', 'kilo-code'];
69
+ if (Array.isArray(frontmatter.platforms)) {
70
+ for (const p of frontmatter.platforms) {
71
+ if (!validPlatforms.includes(p)) {
72
+ console.error(`❌ [${skillName}] Invalid platform: ${p}`);
73
+ hasErrors = true;
74
+ }
75
+ }
76
+ }
77
+
78
+ if (!content.includes('> **Language rule:**')) {
79
+ console.error(`❌ [${skillName}] Missing Language Rule declaration.`);
80
+ hasErrors = true;
81
+ }
82
+
83
+ const body = parsed.content;
84
+ const required = [...REQUIRED_FOR_ALL];
85
+ if (ACTION_SKILLS.includes(skillName)) {
86
+ required.push(...REQUIRED_FOR_ACTION);
87
+ }
88
+ if (EXECUTION_SKILLS.includes(skillName)) {
89
+ required.push(...REQUIRED_FOR_EXECUTION);
90
+ }
91
+
92
+ for (const section of required) {
93
+ const headingRegex = new RegExp(`^##\\s+${section}\\b`, 'm');
94
+ if (!headingRegex.test(body)) {
95
+ console.error(`❌ [${skillName}] Missing section: ## ${section}`);
96
+ hasErrors = true;
97
+ }
98
+ }
99
+ }
100
+
101
+ console.log('🔍 Running V7.5 Skill Schema Linting...');
102
+
103
+ const items = fs.readdirSync(skillsDir);
104
+ for (const item of items) {
105
+ if (item === '_template' || item === 'qk-policy-engine') continue;
106
+
107
+ const skillDir = path.join(skillsDir, item);
108
+ if (fs.statSync(skillDir).isDirectory() && item.startsWith('qk-')) {
109
+ const skillMdPath = path.join(skillDir, 'SKILL.md');
110
+ if (fs.existsSync(skillMdPath)) {
111
+ lintSkill(skillMdPath, item);
112
+ }
113
+ }
114
+ }
115
+
116
+ if (hasErrors) {
117
+ console.error('\n💥 Linting failed. One or more skills do not comply with the V7.5 Runtime Standard.');
118
+ process.exit(1);
119
+ } else {
120
+ console.log('\n✅ All skills comply with V7.5 Runtime Standard!');
121
+ process.exit(0);
122
+ }
123
+