ai-developer-skill-os 9.3.0 → 10.1.0

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 (185) hide show
  1. package/.agents/AGENTS.md +60 -40
  2. package/.agents/DEV_PROFILE.md +36 -2
  3. package/.agents/registry/graph.json +95 -342
  4. package/.agents/registry/index.yaml +61 -237
  5. package/.agents/rules/coding.md +30 -12
  6. package/.agents/rules/command-safety.md +19 -8
  7. package/.agents/rules/global.md +234 -28
  8. package/.agents/rules/prompt-compiler.md +170 -0
  9. package/.agents/skills/qk-api-data-discovery/SKILL.md +470 -0
  10. package/.agents/skills/qk-backend-data/SKILL.md +190 -0
  11. package/.agents/skills/qk-bug-resolution/SKILL.md +176 -248
  12. package/.agents/skills/qk-code-cleaner/SKILL.md +250 -0
  13. package/.agents/skills/qk-code-review/SKILL.md +126 -247
  14. package/.agents/skills/qk-devops-release/SKILL.md +145 -0
  15. package/.agents/skills/qk-feature-delivery/SKILL.md +179 -247
  16. package/.agents/skills/qk-orchestrator/SKILL.md +100 -151
  17. package/.agents/skills/qk-product-spec/SKILL.md +113 -0
  18. package/.agents/skills/qk-prompt-compiler/SKILL.md +321 -0
  19. package/.agents/skills/qk-ui-engineer/SKILL.md +137 -0
  20. package/.agents/workflows/feature-delivery.yml +1 -1
  21. package/.agents/workflows/production-release.yml +1 -1
  22. package/.agents/workflows/spec-driven-development.yml +109 -87
  23. package/CHANGELOG.md +54 -0
  24. package/README.md +125 -184
  25. package/bin/install.js +337 -329
  26. package/package.json +2 -2
  27. package/.agents/README.md +0 -90
  28. package/.agents/docs/CHI_TIET_SKILLS.md +0 -126
  29. package/.agents/docs/HUONG_DAN_SU_DUNG.md +0 -120
  30. package/.agents/docs/MIGRATION-CLEANUP-V8.1.3.md +0 -36
  31. package/.agents/docs/MIGRATION-STATUS.md +0 -35
  32. package/.agents/docs/MIGRATION-V8.md +0 -10
  33. package/.agents/docs/ROADMAP-V8.2.md +0 -78
  34. package/.agents/docs/V8-CERTIFICATION.md +0 -27
  35. package/.agents/skills/qk-access-policy/SKILL.md +0 -206
  36. package/.agents/skills/qk-access-policy/capability.yaml +0 -23
  37. package/.agents/skills/qk-access-policy/evals/scorecard.yaml +0 -36
  38. package/.agents/skills/qk-agent-observability/SKILL.md +0 -108
  39. package/.agents/skills/qk-agent-observability/capability.yaml +0 -29
  40. package/.agents/skills/qk-agent-observability/evals/scorecard.yaml +0 -29
  41. package/.agents/skills/qk-agent-observability/references/scorecard.yaml +0 -80
  42. package/.agents/skills/qk-ai-builder/SKILL.md +0 -254
  43. package/.agents/skills/qk-ai-builder/capability.yaml +0 -23
  44. package/.agents/skills/qk-ai-builder/evals/scorecard.yaml +0 -30
  45. package/.agents/skills/qk-api-consumer/SKILL.md +0 -256
  46. package/.agents/skills/qk-api-consumer/capability.yaml +0 -21
  47. package/.agents/skills/qk-api-consumer/evals/scorecard.yaml +0 -29
  48. package/.agents/skills/qk-api-lifecycle/SKILL.md +0 -251
  49. package/.agents/skills/qk-api-lifecycle/capability.yaml +0 -23
  50. package/.agents/skills/qk-api-lifecycle/evals/scorecard.yaml +0 -29
  51. package/.agents/skills/qk-bug-resolution/capability.yaml +0 -25
  52. package/.agents/skills/qk-code-review/capability.yaml +0 -23
  53. package/.agents/skills/qk-context-loader/SKILL.md +0 -198
  54. package/.agents/skills/qk-context-loader/capability.yaml +0 -23
  55. package/.agents/skills/qk-context-loader/evals/scorecard.yaml +0 -28
  56. package/.agents/skills/qk-data-engineer/SKILL.md +0 -253
  57. package/.agents/skills/qk-data-lifecycle/SKILL.md +0 -197
  58. package/.agents/skills/qk-data-lifecycle/capability.yaml +0 -23
  59. package/.agents/skills/qk-data-lifecycle/evals/scorecard.yaml +0 -29
  60. package/.agents/skills/qk-db-optimizer/SKILL.md +0 -210
  61. package/.agents/skills/qk-db-optimizer/capability.yaml +0 -22
  62. package/.agents/skills/qk-db-optimizer/evals/scorecard.yaml +0 -28
  63. package/.agents/skills/qk-design-system-engineering/SKILL.md +0 -193
  64. package/.agents/skills/qk-design-system-engineering/capability.yaml +0 -25
  65. package/.agents/skills/qk-design-system-engineering/evals/scorecard.yaml +0 -27
  66. package/.agents/skills/qk-devops-platform/SKILL.md +0 -198
  67. package/.agents/skills/qk-devops-platform/capability.yaml +0 -29
  68. package/.agents/skills/qk-devops-platform/evals/scorecard.yaml +0 -28
  69. package/.agents/skills/qk-docs/SKILL.md +0 -193
  70. package/.agents/skills/qk-docs/capability.yaml +0 -23
  71. package/.agents/skills/qk-docs/evals/scorecard.yaml +0 -27
  72. package/.agents/skills/qk-engineering-standard/SKILL.md +0 -89
  73. package/.agents/skills/qk-engineering-standard/capability.yaml +0 -23
  74. package/.agents/skills/qk-engineering-standard/evals/scorecard.yaml +0 -28
  75. package/.agents/skills/qk-engineering-standard/references/anti-patterns.md +0 -121
  76. package/.agents/skills/qk-engineering-standard/rules/backend.md +0 -122
  77. package/.agents/skills/qk-engineering-standard/rules/database.md +0 -3
  78. package/.agents/skills/qk-engineering-standard/rules/frontend.md +0 -152
  79. package/.agents/skills/qk-engineering-standard/rules/security.md +0 -3
  80. package/.agents/skills/qk-engineering-standard/rules/testing.md +0 -3
  81. package/.agents/skills/qk-fe-api-integration/SKILL.md +0 -704
  82. package/.agents/skills/qk-fe-api-integration/capability.yaml +0 -21
  83. package/.agents/skills/qk-fe-api-integration/evals/scorecard.yaml +0 -29
  84. package/.agents/skills/qk-feature-delivery/capability.yaml +0 -24
  85. package/.agents/skills/qk-frontend-architecture/SKILL.md +0 -127
  86. package/.agents/skills/qk-frontend-architecture/capability.yaml +0 -28
  87. package/.agents/skills/qk-frontend-architecture/evals/scorecard.yaml +0 -28
  88. package/.agents/skills/qk-help/SKILL.md +0 -107
  89. package/.agents/skills/qk-help/capability.yaml +0 -20
  90. package/.agents/skills/qk-help/evals/scorecard.yaml +0 -13
  91. package/.agents/skills/qk-orchestrator/capability.yaml +0 -22
  92. package/.agents/skills/qk-product-specification/SKILL.md +0 -187
  93. package/.agents/skills/qk-product-specification/capability.yaml +0 -27
  94. package/.agents/skills/qk-product-specification/evals/scorecard.yaml +0 -27
  95. package/.agents/skills/qk-production-release/SKILL.md +0 -188
  96. package/.agents/skills/qk-production-release/capability.yaml +0 -27
  97. package/.agents/skills/qk-production-release/evals/scorecard.yaml +0 -28
  98. package/.agents/skills/qk-project-audit/SKILL.md +0 -174
  99. package/.agents/skills/qk-project-bootstrap/SKILL.md +0 -372
  100. package/.agents/skills/qk-project-bootstrap/capability.yaml +0 -23
  101. package/.agents/skills/qk-project-bootstrap/evals/scorecard.yaml +0 -28
  102. package/.agents/skills/qk-project-health/SKILL.md +0 -202
  103. package/.agents/skills/qk-project-health/capability.yaml +0 -23
  104. package/.agents/skills/qk-project-health/evals/scorecard.yaml +0 -27
  105. package/.agents/skills/qk-project-memory/SKILL.md +0 -303
  106. package/.agents/skills/qk-project-memory/capability.yaml +0 -23
  107. package/.agents/skills/qk-project-memory/evals/scorecard.yaml +0 -27
  108. package/.agents/skills/qk-refactor/SKILL.md +0 -243
  109. package/.agents/skills/qk-refactor/capability.yaml +0 -26
  110. package/.agents/skills/qk-refactor/evals/scorecard.yaml +0 -27
  111. package/.agents/skills/qk-security-audit/SKILL.md +0 -280
  112. package/.agents/skills/qk-security-audit/capability.yaml +0 -29
  113. package/.agents/skills/qk-security-audit/evals/scorecard.yaml +0 -27
  114. package/.agents/skills/qk-system-evolution/SKILL.md +0 -625
  115. package/.agents/skills/qk-system-evolution/capability.yaml +0 -24
  116. package/.agents/skills/qk-system-evolution/evals/scorecard.yaml +0 -26
  117. package/.agents/skills/qk-test-engineering/SKILL.md +0 -215
  118. package/.agents/skills/qk-test-engineering/capability.yaml +0 -28
  119. package/.agents/skills/qk-test-engineering/evals/scorecard.yaml +0 -26
  120. package/.agents/skills/qk-ui-audit/SKILL.md +0 -175
  121. package/.agents/skills/qk-ui-audit/capability.yaml +0 -23
  122. package/.agents/skills/qk-ui-audit/evals/scorecard.yaml +0 -26
  123. package/.agents/skills/qk-ui-audit/references/anti-slop-checklist.md +0 -136
  124. package/.agents/skills/qk-ui-builder/SKILL.md +0 -521
  125. package/.agents/skills/qk-ui-builder/capability.yaml +0 -29
  126. package/.agents/skills/qk-ui-builder/evals/scorecard.yaml +0 -26
  127. package/.agents/skills/qk-ui-builder/references/anti-patterns.md +0 -295
  128. package/.agents/skills/qk-ui-builder/references/color.md +0 -115
  129. package/.agents/skills/qk-ui-builder/references/component-cookbook.md +0 -458
  130. package/.agents/skills/qk-ui-builder/references/copy.md +0 -250
  131. package/.agents/skills/qk-ui-builder/references/interaction-and-states.md +0 -115
  132. package/.agents/skills/qk-ui-builder/references/layout-and-space.md +0 -111
  133. package/.agents/skills/qk-ui-builder/references/macrostructures/01-bento-grid.md +0 -48
  134. package/.agents/skills/qk-ui-builder/references/macrostructures/02-long-document.md +0 -50
  135. package/.agents/skills/qk-ui-builder/references/macrostructures/03-marquee-hero.md +0 -51
  136. package/.agents/skills/qk-ui-builder/references/macrostructures/04-stat-led.md +0 -49
  137. package/.agents/skills/qk-ui-builder/references/macrostructures/05-workbench.md +0 -44
  138. package/.agents/skills/qk-ui-builder/references/macrostructures/06-conversational-faq.md +0 -50
  139. package/.agents/skills/qk-ui-builder/references/macrostructures/07-manifesto.md +0 -51
  140. package/.agents/skills/qk-ui-builder/references/macrostructures/08-photographic.md +0 -50
  141. package/.agents/skills/qk-ui-builder/references/macrostructures/09-quote-led.md +0 -50
  142. package/.agents/skills/qk-ui-builder/references/macrostructures/11-catalogue.md +0 -49
  143. package/.agents/skills/qk-ui-builder/references/macrostructures/12-letter.md +0 -49
  144. package/.agents/skills/qk-ui-builder/references/macrostructures/13-index-first.md +0 -49
  145. package/.agents/skills/qk-ui-builder/references/macrostructures/14-narrative-workflow.md +0 -48
  146. package/.agents/skills/qk-ui-builder/references/macrostructures/15-split-studio.md +0 -48
  147. package/.agents/skills/qk-ui-builder/references/macrostructures/16-feature-stack.md +0 -51
  148. package/.agents/skills/qk-ui-builder/references/macrostructures/17-type-specimen.md +0 -48
  149. package/.agents/skills/qk-ui-builder/references/macrostructures/18-portfolio-grid.md +0 -48
  150. package/.agents/skills/qk-ui-builder/references/macrostructures/19-map-diagram.md +0 -50
  151. package/.agents/skills/qk-ui-builder/references/macrostructures/20-ecosystem-index.md +0 -48
  152. package/.agents/skills/qk-ui-builder/references/macrostructures/21-component-playground.md +0 -45
  153. package/.agents/skills/qk-ui-builder/references/macrostructures.md +0 -38
  154. package/.agents/skills/qk-ui-builder/references/motion.md +0 -95
  155. package/.agents/skills/qk-ui-builder/references/responsive.md +0 -115
  156. package/.agents/skills/qk-ui-builder/references/slop-test.md +0 -135
  157. package/.agents/skills/qk-ui-builder/references/structure.md +0 -280
  158. package/.agents/skills/qk-ui-builder/references/themes/atmospheric.md +0 -53
  159. package/.agents/skills/qk-ui-builder/references/themes/carnival.md +0 -52
  160. package/.agents/skills/qk-ui-builder/references/themes/cobalt.md +0 -52
  161. package/.agents/skills/qk-ui-builder/references/themes/editorial.md +0 -52
  162. package/.agents/skills/qk-ui-builder/references/themes/garden.md +0 -52
  163. package/.agents/skills/qk-ui-builder/references/themes/hum.md +0 -52
  164. package/.agents/skills/qk-ui-builder/references/themes/lumen.md +0 -52
  165. package/.agents/skills/qk-ui-builder/references/themes/midnight.md +0 -52
  166. package/.agents/skills/qk-ui-builder/references/themes/modern-minimal.md +0 -52
  167. package/.agents/skills/qk-ui-builder/references/themes/playful.md +0 -52
  168. package/.agents/skills/qk-ui-builder/references/themes/specimen.md +0 -52
  169. package/.agents/skills/qk-ui-builder/references/themes/terminal.md +0 -52
  170. package/.agents/skills/qk-ui-builder/references/typography.md +0 -129
  171. package/.agents/skills/qk-ui-system-builder/SKILL.md +0 -183
  172. package/.agents/skills/qk-ui-system-builder/capability.yaml +0 -25
  173. package/.agents/skills/qk-ui-system-builder/evals/scorecard.yaml +0 -26
  174. package/.agents/skills/qk-upgrade/SKILL.md +0 -301
  175. package/.agents/skills/qk-upgrade/capability.yaml +0 -24
  176. package/.agents/skills/qk-upgrade/evals/scorecard.yaml +0 -26
  177. package/.agents/skills/qk-validation-gate/SKILL.md +0 -88
  178. package/.agents/skills/qk-validation-gate/capability.yaml +0 -23
  179. package/.agents/skills/qk-validation-gate/evals/scorecard.yaml +0 -26
  180. package/.agents/skills/qk-web-quality-gate/SKILL.md +0 -197
  181. package/.agents/skills/qk-web-quality-gate/capability.yaml +0 -24
  182. package/.agents/skills/qk-web-quality-gate/evals/scorecard.yaml +0 -26
  183. package/.agents/workflows/research.yml +0 -75
  184. package/.agents/workflows/skill-evolution.yml +0 -97
  185. package/tooling/fix-refactor.js +0 -8
package/bin/install.js CHANGED
@@ -1,330 +1,338 @@
1
1
  #!/usr/bin/env node
2
-
3
- import fs from 'fs';
4
- import path from 'path';
5
- import readline from 'readline';
6
- import { fileURLToPath } from 'url';
7
- import os from 'os';
8
-
9
- const __filename = fileURLToPath(import.meta.url);
10
- const __dirname = path.dirname(__filename);
11
- const sourceDir = path.resolve(__dirname, '..', '.agents');
12
- const packageJsonPath = path.resolve(__dirname, '..', 'package.json');
13
- const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
14
- const version = pkg.version;
15
- const cwd = process.cwd();
16
- const homeDir = os.homedir();
17
-
18
- // Version marker file written after every successful install
19
- const VERSION_FILE = '.ai-skill-os-version';
20
-
21
- // ─── IDE Configuration Map ────────────────────────────────────────────────────
22
- // Each IDE has:
23
- // localDir — where to install when scope=local (relative to cwd)
24
- // globalDir — where to install when scope=global (absolute, user-level)
25
- // postInstall — special steps after copy (null = none)
26
- // ─────────────────────────────────────────────────────────────────────────────
27
- const IDE_CONFIG = {
28
- antigravity: {
29
- label: 'Antigravity (Google Gemini)',
30
- localDir: path.join(cwd, '.agents'),
31
- globalDir: path.join(homeDir, '.gemini', 'config'),
32
- postInstall: 'rewriteAbsolutePaths',
33
- note: 'Global: ~/.gemini/config — applies to all projects on this machine',
34
- },
35
- claude: {
36
- label: 'Claude Code (Anthropic)',
37
- localDir: path.join(cwd, '.claude'),
38
- globalDir: path.join(homeDir, '.claude'),
39
- postInstall: 'renameToClaude',
40
- note: 'Global: ~/.claude/CLAUDE.md — applies to all Claude Code sessions',
41
- },
42
- cursor: {
43
- label: 'Cursor IDE',
44
- localDir: path.join(cwd, '.cursor', 'rules'),
45
- globalDir: null, // Cursor has no reliable global rules path — use Settings UI
46
- postInstall: 'exportCursorRules',
47
- note: 'Local only: .cursor/rules/ — use Cursor Settings > Rules for AI for global rules',
48
- },
49
- codex: {
50
- label: 'OpenAI Codex CLI',
51
- localDir: path.join(cwd, '.codex'),
52
- globalDir: path.join(homeDir, '.codex'),
53
- postInstall: null,
54
- note: 'Global: ~/.codex — applies to all Codex CLI sessions',
55
- },
56
- };
57
-
58
- // ─── Utilities ───────────────────────────────────────────────────────────────
59
-
60
- function copyRecursiveSync(src, dest) {
61
- if (!fs.existsSync(src)) return;
62
- const stats = fs.statSync(src);
63
- if (stats.isDirectory()) {
64
- fs.mkdirSync(dest, { recursive: true });
65
- for (const child of fs.readdirSync(src)) {
66
- copyRecursiveSync(path.join(src, child), path.join(dest, child));
67
- }
68
- } else {
69
- fs.mkdirSync(path.dirname(dest), { recursive: true });
70
- fs.copyFileSync(src, dest);
71
- }
72
- }
73
-
74
- /** Read installed version from marker file. Returns null if not installed. */
75
- function getInstalledVersion(targetDir) {
76
- const markerPath = path.join(targetDir, VERSION_FILE);
77
- if (!fs.existsSync(markerPath)) return null;
78
- try {
79
- return fs.readFileSync(markerPath, 'utf8').trim();
80
- } catch {
81
- return null;
82
- }
83
- }
84
-
85
- /** Write version marker after successful install. */
86
- function writeVersionMarker(targetDir) {
87
- fs.writeFileSync(
88
- path.join(targetDir, VERSION_FILE),
89
- `${version}\nInstalled: ${new Date().toISOString()}\n`,
90
- 'utf8'
91
- );
92
- }
93
-
94
- /** Remove existing install. For Cursor: only delete the .mdc rule file. */
95
- function removeExistingInstall(targetDir, ide) {
96
- if (ide === 'cursor') {
97
- const mdcPath = path.join(targetDir, 'ai-skill-os.mdc');
98
- if (fs.existsSync(mdcPath)) fs.unlinkSync(mdcPath);
99
- console.log(' 🗑️ Removed old Cursor rule: ai-skill-os.mdc');
100
- } else {
101
- if (fs.existsSync(targetDir)) {
102
- fs.rmSync(targetDir, { recursive: true, force: true });
103
- console.log(` 🗑️ Removed old install: ${targetDir}`);
104
- }
105
- }
106
- }
107
-
108
- /** Prompt user yes/no. Resolves true for yes. */
109
- function confirm(rl, question) {
110
- return new Promise((resolve) => {
111
- rl.question(question, (ans) => resolve(['y', 'yes', ''].includes(ans.trim().toLowerCase())));
112
- });
113
- }
114
-
115
- function parseArgs() {
116
- const args = process.argv.slice(2);
117
- const result = { ide: null, scope: null };
118
- for (const arg of args) {
119
- if (arg.startsWith('--ide=')) result.ide = arg.split('=')[1];
120
- else if (arg.startsWith('--scope=')) result.scope = arg.split('=')[1];
121
- }
122
- return result;
123
- }
124
-
125
- // ─── Post-install handlers ────────────────────────────────────────────────────
126
-
127
- /**
128
- * Antigravity global install: rewrite relative .agents/X paths → absolute paths.
129
- * Required because Antigravity reads SKILL.md files from an absolute global path.
130
- */
131
- function rewriteAbsolutePaths(targetDir) {
132
- const targetPosix = targetDir.replace(/\\/g, '/');
133
- const DIRS_TO_REWRITE = ['skills', 'registry', 'rules', 'workflows', 'knowledge', 'docs', 'blueprints'];
134
-
135
- const walk = (dir) => {
136
- for (const file of fs.readdirSync(dir)) {
137
- const fullPath = path.join(dir, file);
138
- if (fs.statSync(fullPath).isDirectory()) {
139
- walk(fullPath);
140
- } else if (/\.(md|yml|yaml|json)$/.test(fullPath)) {
141
- let content = fs.readFileSync(fullPath, 'utf8');
142
- let changed = false;
143
-
144
- for (const d of DIRS_TO_REWRITE) {
145
- const re = new RegExp(`\\.agents/${d}`, 'g');
146
- if (re.test(content)) {
147
- content = content.replace(re, `${targetPosix}/${d}`);
148
- changed = true;
149
- }
150
- }
151
- if (content.includes('.agents/skills.json')) {
152
- content = content.replace(/\.agents\/skills\.json/g, `${targetPosix}/skills.json`);
153
- changed = true;
154
- }
155
- if (changed) fs.writeFileSync(fullPath, content, 'utf8');
156
- }
157
- }
158
- };
159
-
160
- walk(targetDir);
161
- console.log(' ✅ Rewrote .agents/* references → absolute paths for Antigravity global mode');
162
- }
163
-
164
- /**
165
- * Claude Code install: copy AGENTS.md → CLAUDE.md at target root.
166
- * Claude Code reads ~/.claude/CLAUDE.md as global instructions.
167
- */
168
- function renameToClaude(targetDir) {
169
- const agentsMd = path.join(targetDir, 'AGENTS.md');
170
- const claudeMd = path.join(targetDir, 'CLAUDE.md');
171
-
172
- if (fs.existsSync(agentsMd) && !fs.existsSync(claudeMd)) {
173
- fs.copyFileSync(agentsMd, claudeMd);
174
- console.log(' ✅ Copied AGENTS.md → CLAUDE.md (Claude Code entry point)');
175
- } else if (fs.existsSync(claudeMd)) {
176
- console.log(' ℹ️ CLAUDE.md already exists — skipped overwrite');
177
- }
178
- }
179
-
180
- /**
181
- * Cursor install: export AGENTS.md content as a .mdc rule file.
182
- * Cursor reads .cursor/rules/*.mdc — each file needs YAML frontmatter.
183
- */
184
- function exportCursorRules(targetDir) {
185
- const agentsMd = path.join(sourceDir, 'AGENTS.md');
186
- if (!fs.existsSync(agentsMd)) return;
187
-
188
- const rawContent = fs.readFileSync(agentsMd, 'utf8');
189
- const mdcContent = `---
190
- description: "AI Developer Skill OS v${version} — global skill rules"
191
- alwaysApply: true
192
- ---
193
-
194
- ${rawContent}`;
195
-
196
- const outPath = path.join(targetDir, 'ai-skill-os.mdc');
197
- fs.mkdirSync(targetDir, { recursive: true });
198
- fs.writeFileSync(outPath, mdcContent, 'utf8');
199
- console.log(` ✅ Exported rules → ${outPath}`);
200
- console.log(' ℹ️ For global rules: Cursor Settings > General > Rules for AI');
201
- }
202
-
203
- // ─── Main install logic ───────────────────────────────────────────────────────
204
-
205
- async function runInstall(ideKey, scopeKey, rl) {
206
- const ideMap = { '1': 'antigravity', '2': 'claude', '3': 'cursor', '4': 'codex' };
207
- const scopeMap = { '1': 'local', '2': 'global' };
208
-
209
- const ide = ideMap[ideKey] || ideKey;
210
- const scope = scopeMap[scopeKey] || scopeKey;
211
- const config = IDE_CONFIG[ide];
212
-
213
- if (!config) {
214
- console.error(`❌ IDE không hợp lệ: "${ide}". Chọn: antigravity, claude, cursor, codex`);
215
- process.exit(1);
216
- }
217
-
218
- const isGlobal = scope === 'global';
219
-
220
- if (isGlobal && config.globalDir === null) {
221
- console.warn(`⚠️ ${config.label} không hỗ trợ cài Global qua file.`);
222
- console.warn(` ${config.note}`);
223
- console.warn(' Tiến hành cài Local thay thế...');
224
- }
225
-
226
- const targetDir = (isGlobal && config.globalDir) ? config.globalDir : config.localDir;
227
-
228
- console.log(`\n🚀 AI Developer Skill OS v${version}`);
229
- console.log(` IDE: ${config.label}`);
230
- console.log(` Scope: ${isGlobal ? 'Global' : 'Local'}`);
231
- console.log(` Path: ${targetDir}`);
232
-
233
- // ── Version check ────────────────────────────────────────────────────────
234
- const installedVersion = getInstalledVersion(targetDir);
235
-
236
- if (installedVersion) {
237
- if (installedVersion === version) {
238
- console.log(`\n✅ Phiên bản v${version} đã được cài đặt — không cần cập nhật.`);
239
- console.log(' Dùng --force để cài lại.\n');
240
- const isForce = process.argv.includes('--force');
241
- if (!isForce) {
242
- if (rl) rl.close();
243
- return;
244
- }
245
- console.log(' --force detected: tiến hành cài lại...');
246
- } else {
247
- console.log(`\n⚠️ Phát hiện phiên bản cũ: v${installedVersion}`);
248
- console.log(` Phiên bản mới: v${version}`);
249
- const shouldUpgrade = rl
250
- ? await confirm(rl, '\n Xóa bản cũ và cài bản mới? [Y/n]: ')
251
- : true;
252
- if (!shouldUpgrade) {
253
- console.log(' Hủy cài đặt.');
254
- if (rl) rl.close();
255
- return;
256
- }
257
- }
258
- // Remove old install before fresh copy
259
- removeExistingInstall(targetDir, ide);
260
- } else {
261
- console.log(' (Chưa cài đặt — fresh install)\n');
262
- }
263
-
264
- // ── Install ──────────────────────────────────────────────────────────────
265
- try {
266
- if (!fs.existsSync(sourceDir)) {
267
- console.error(`❌ Không tìm thấy source: ${sourceDir}`);
268
- process.exit(1);
269
- }
270
-
271
- if (ide === 'cursor') {
272
- exportCursorRules(targetDir);
273
- } else {
274
- copyRecursiveSync(sourceDir, targetDir);
275
- console.log(` ✅ Copied .agents/ → ${targetDir}`);
276
-
277
- if (isGlobal && config.postInstall === 'rewriteAbsolutePaths') {
278
- rewriteAbsolutePaths(targetDir);
279
- }
280
- if (config.postInstall === 'renameToClaude') {
281
- renameToClaude(targetDir);
282
- }
283
- }
284
-
285
- writeVersionMarker(targetDir);
286
- console.log(`\n🎉 Hoàn tất v${version}! ${config.note}\n`);
287
-
288
- } catch (err) {
289
- console.error('❌ Lỗi cài đặt:', err.message);
290
- process.exit(1);
291
- } finally {
292
- if (rl) rl.close();
293
- }
294
- }
295
-
296
- // ─── CLI entry point ──────────────────────────────────────────────────────────
297
-
298
- const args = parseArgs();
299
-
300
- if (args.ide && args.scope) {
301
- // Non-interactive mode (called via npm scripts)
302
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
303
- await runInstall(args.ide, args.scope, rl);
304
- } else {
305
- // Interactive mode
306
- console.log(`\n🚀 AI Developer Skill OS v${version} — Setup\n`);
307
-
308
- const ideQuestion = `Chọn IDE/AI Assistant:
309
- (1) Antigravity (Google Gemini)
310
- (2) Claude Code (Anthropic)
311
- (3) Cursor IDE
312
- (4) OpenAI Codex CLI
313
-
314
- Nhập số (1-4): `;
315
-
316
- const scopeQuestion = `
317
- Phạm vi cài đặt:
318
- (1) Local — Chỉ dự án này (.agents/ hoặc .claude/ trong thư mục hiện tại)
319
- (2) Global — Toàn bộ máy tính (áp dụng cho mọi dự án)
320
-
321
- Nhập số (1-2): `;
322
-
323
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
324
-
325
- rl.question(ideQuestion, async (ideAnswer) => {
326
- rl.question(scopeQuestion, async (scopeAnswer) => {
327
- await runInstall(ideAnswer.trim(), scopeAnswer.trim(), rl);
328
- });
329
- });
330
- }
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import readline from 'readline';
6
+ import { fileURLToPath } from 'url';
7
+ import os from 'os';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ const sourceDir = path.resolve(__dirname, '..', '.agents');
12
+ const packageJsonPath = path.resolve(__dirname, '..', 'package.json');
13
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
14
+ const version = pkg.version;
15
+ const cwd = process.cwd();
16
+ const homeDir = os.homedir();
17
+
18
+ // Version marker file written after every successful install
19
+ const VERSION_FILE = '.ai-skill-os-version';
20
+
21
+ // ─── IDE Configuration Map ────────────────────────────────────────────────────
22
+ // Each IDE has:
23
+ // localDir — where to install when scope=local (relative to cwd)
24
+ // globalDir — where to install when scope=global (absolute, user-level)
25
+ // postInstall — special steps after copy (null = none)
26
+ // ─────────────────────────────────────────────────────────────────────────────
27
+ const IDE_CONFIG = {
28
+ antigravity: {
29
+ label: 'Antigravity (Google Gemini)',
30
+ localDir: path.join(cwd, '.agents'),
31
+ globalDir: path.join(homeDir, '.gemini', 'config'),
32
+ postInstall: 'rewriteAbsolutePaths',
33
+ note: 'Global: ~/.gemini/config — applies to all projects on this machine',
34
+ },
35
+ claude: {
36
+ label: 'Claude Code (Anthropic)',
37
+ localDir: path.join(cwd, '.claude'),
38
+ globalDir: path.join(homeDir, '.claude'),
39
+ postInstall: 'renameToClaude',
40
+ note: 'Global: ~/.claude/CLAUDE.md — applies to all Claude Code sessions',
41
+ },
42
+ cursor: {
43
+ label: 'Cursor IDE',
44
+ localDir: path.join(cwd, '.cursor', 'rules'),
45
+ globalDir: null, // Cursor has no reliable global rules path — use Settings UI
46
+ postInstall: 'exportCursorRules',
47
+ note: 'Local only: .cursor/rules/ — use Cursor Settings > Rules for AI for global rules',
48
+ },
49
+ codex: {
50
+ label: 'OpenAI Codex CLI',
51
+ localDir: path.join(cwd, '.codex'),
52
+ globalDir: path.join(homeDir, '.codex'),
53
+ postInstall: null,
54
+ note: 'Global: ~/.codex — applies to all Codex CLI sessions',
55
+ },
56
+ };
57
+
58
+ // ─── Utilities ───────────────────────────────────────────────────────────────
59
+
60
+ function copyRecursiveSync(src, dest) {
61
+ if (!fs.existsSync(src)) return;
62
+ const stats = fs.statSync(src);
63
+ if (stats.isDirectory()) {
64
+ fs.mkdirSync(dest, { recursive: true });
65
+ for (const child of fs.readdirSync(src)) {
66
+ copyRecursiveSync(path.join(src, child), path.join(dest, child));
67
+ }
68
+ } else {
69
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
70
+ fs.copyFileSync(src, dest);
71
+ }
72
+ }
73
+
74
+ /** Read installed version from marker file. Returns null if not installed. */
75
+ function getInstalledVersion(targetDir) {
76
+ const markerPath = path.join(targetDir, VERSION_FILE);
77
+ if (!fs.existsSync(markerPath)) return null;
78
+ try {
79
+ return fs.readFileSync(markerPath, 'utf8').trim();
80
+ } catch {
81
+ return null;
82
+ }
83
+ }
84
+
85
+ /** Write version marker after successful install. */
86
+ function writeVersionMarker(targetDir) {
87
+ fs.writeFileSync(
88
+ path.join(targetDir, VERSION_FILE),
89
+ `${version}\nInstalled: ${new Date().toISOString()}\n`,
90
+ 'utf8'
91
+ );
92
+ }
93
+
94
+ /** Remove existing install. For Cursor: only delete the .mdc rule file. */
95
+ function removeExistingInstall(targetDir, ide) {
96
+ if (ide === 'cursor') {
97
+ const mdcPath = path.join(targetDir, 'ai-skill-os.mdc');
98
+ if (fs.existsSync(mdcPath)) fs.unlinkSync(mdcPath);
99
+ console.log(' 🗑️ Removed old Cursor rule: ai-skill-os.mdc');
100
+ } else {
101
+ if (fs.existsSync(targetDir)) {
102
+ fs.rmSync(targetDir, { recursive: true, force: true });
103
+ console.log(` 🗑️ Removed old install: ${targetDir}`);
104
+ }
105
+ }
106
+ }
107
+
108
+ /** Prompt user yes/no. Resolves true for yes. */
109
+ function confirm(rl, question) {
110
+ return new Promise((resolve) => {
111
+ rl.question(question, (ans) => resolve(['y', 'yes', ''].includes(ans.trim().toLowerCase())));
112
+ });
113
+ }
114
+
115
+ function parseArgs() {
116
+ const args = process.argv.slice(2);
117
+ const result = { ide: null, scope: null };
118
+ for (const arg of args) {
119
+ if (arg.startsWith('--ide=')) result.ide = arg.split('=')[1];
120
+ else if (arg.startsWith('--scope=')) result.scope = arg.split('=')[1];
121
+ }
122
+ return result;
123
+ }
124
+
125
+ // ─── Post-install handlers ────────────────────────────────────────────────────
126
+
127
+ /**
128
+ * Antigravity global install: rewrite relative .agents/X paths → absolute paths.
129
+ * Required because Antigravity reads SKILL.md files from an absolute global path.
130
+ */
131
+ function rewriteAbsolutePaths(targetDir) {
132
+ const targetPosix = targetDir.replace(/\\/g, '/');
133
+ const DIRS_TO_REWRITE = ['skills', 'registry', 'rules', 'workflows', 'knowledge', 'docs', 'blueprints'];
134
+
135
+ const walk = (dir) => {
136
+ for (const file of fs.readdirSync(dir)) {
137
+ const fullPath = path.join(dir, file);
138
+ if (fs.statSync(fullPath).isDirectory()) {
139
+ walk(fullPath);
140
+ } else if (/\.(md|yml|yaml|json)$/.test(fullPath)) {
141
+ let content = fs.readFileSync(fullPath, 'utf8');
142
+ let changed = false;
143
+
144
+ for (const d of DIRS_TO_REWRITE) {
145
+ const re = new RegExp(`\\.agents/${d}`, 'g');
146
+ if (re.test(content)) {
147
+ content = content.replace(re, () => `${targetPosix}/${d}`);
148
+ changed = true;
149
+ }
150
+ }
151
+ if (content.includes('.agents/skills.json')) {
152
+ content = content.replace(/\.agents\/skills\.json/g, () => `${targetPosix}/skills.json`);
153
+ changed = true;
154
+ }
155
+ if (changed) fs.writeFileSync(fullPath, content, 'utf8');
156
+ }
157
+ }
158
+ };
159
+
160
+ walk(targetDir);
161
+ console.log(' ✅ Rewrote .agents/* references → absolute paths for Antigravity global mode');
162
+ }
163
+
164
+ /**
165
+ * Claude Code install: copy AGENTS.md → CLAUDE.md at target root.
166
+ * Claude Code reads ~/.claude/CLAUDE.md as global instructions.
167
+ */
168
+ function renameToClaude(targetDir) {
169
+ const agentsMd = path.join(targetDir, 'AGENTS.md');
170
+ const claudeMd = path.join(targetDir, 'CLAUDE.md');
171
+
172
+ if (fs.existsSync(agentsMd) && !fs.existsSync(claudeMd)) {
173
+ fs.copyFileSync(agentsMd, claudeMd);
174
+ console.log(' ✅ Copied AGENTS.md → CLAUDE.md (Claude Code entry point)');
175
+ } else if (fs.existsSync(claudeMd)) {
176
+ console.log(' ℹ️ CLAUDE.md already exists — skipped overwrite');
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Cursor install: export AGENTS.md content as a .mdc rule file.
182
+ * Cursor reads .cursor/rules/*.mdc — each file needs YAML frontmatter.
183
+ */
184
+ function exportCursorRules(targetDir) {
185
+ const agentsMd = path.join(sourceDir, 'AGENTS.md');
186
+ if (!fs.existsSync(agentsMd)) return;
187
+
188
+ const rawContent = fs.readFileSync(agentsMd, 'utf8');
189
+ const mdcContent = `---
190
+ description: "AI Developer Skill OS v${version} — global skill rules"
191
+ alwaysApply: true
192
+ ---
193
+
194
+ ${rawContent}`;
195
+
196
+ const outPath = path.join(targetDir, 'ai-skill-os.mdc');
197
+ fs.mkdirSync(targetDir, { recursive: true });
198
+ fs.writeFileSync(outPath, mdcContent, 'utf8');
199
+ console.log(` ✅ Exported rules → ${outPath}`);
200
+ console.log(' ℹ️ For global rules: Cursor Settings > General > Rules for AI');
201
+ }
202
+
203
+ // ─── Main install logic ───────────────────────────────────────────────────────
204
+
205
+ async function runInstall(ideKey, scopeKey, rl) {
206
+ const ideMap = { '1': 'antigravity', '2': 'claude', '3': 'cursor', '4': 'codex' };
207
+ const scopeMap = { '1': 'local', '2': 'global' };
208
+
209
+ const ide = ideMap[ideKey] || ideKey;
210
+ const scope = scopeMap[scopeKey] || scopeKey;
211
+ const config = IDE_CONFIG[ide];
212
+
213
+ if (!config) {
214
+ console.error(`❌ IDE không hợp lệ: "${ide}". Chọn: antigravity, claude, cursor, codex`);
215
+ process.exit(1);
216
+ }
217
+
218
+ const isGlobal = scope === 'global';
219
+
220
+ if (isGlobal && config.globalDir === null) {
221
+ console.warn(`⚠️ ${config.label} không hỗ trợ cài Global qua file.`);
222
+ console.warn(` ${config.note}`);
223
+ console.warn(' Tiến hành cài Local thay thế...');
224
+ }
225
+
226
+ const targetDir = (isGlobal && config.globalDir) ? config.globalDir : config.localDir;
227
+
228
+ console.log(`\n🚀 AI Developer Skill OS v${version}`);
229
+ console.log(` IDE: ${config.label}`);
230
+ console.log(` Scope: ${isGlobal ? 'Global' : 'Local'}`);
231
+ console.log(` Path: ${targetDir}`);
232
+
233
+ // ── Version check ────────────────────────────────────────────────────────
234
+ const installedVersion = getInstalledVersion(targetDir);
235
+
236
+ if (installedVersion) {
237
+ if (installedVersion === version) {
238
+ console.log(`\n✅ Phiên bản v${version} đã được cài đặt — không cần cập nhật.`);
239
+ console.log(' Dùng --force để cài lại.\n');
240
+ const isForce = process.argv.includes('--force');
241
+ if (!isForce) {
242
+ if (rl) rl.close();
243
+ return;
244
+ }
245
+ console.log(' --force detected: tiến hành cài lại...');
246
+ } else {
247
+ console.log(`\n⚠️ Phát hiện phiên bản cũ: v${installedVersion}`);
248
+ console.log(` Phiên bản mới: v${version}`);
249
+ const shouldUpgrade = rl
250
+ ? await confirm(rl, '\n Xóa bản cũ và cài bản mới? [Y/n]: ')
251
+ : true;
252
+ if (!shouldUpgrade) {
253
+ console.log(' Hủy cài đặt.');
254
+ if (rl) rl.close();
255
+ return;
256
+ }
257
+ }
258
+ // Remove old install before fresh copy
259
+ removeExistingInstall(targetDir, ide);
260
+ } else {
261
+ console.log(' (Chưa cài đặt — fresh install)\n');
262
+ }
263
+
264
+ // ── Install ──────────────────────────────────────────────────────────────
265
+ try {
266
+ if (!fs.existsSync(sourceDir)) {
267
+ console.error(`❌ Không tìm thấy source: ${sourceDir}`);
268
+ process.exit(1);
269
+ }
270
+
271
+ if (ide === 'cursor') {
272
+ exportCursorRules(targetDir);
273
+ } else {
274
+ copyRecursiveSync(sourceDir, targetDir);
275
+ console.log(` ✅ Copied .agents/ → ${targetDir}`);
276
+ if (isGlobal && config.postInstall === 'rewriteAbsolutePaths') {
277
+ rewriteAbsolutePaths(targetDir);
278
+ }
279
+ if (config.postInstall === 'renameToClaude') {
280
+ renameToClaude(targetDir);
281
+ }
282
+ if (ide === 'antigravity') {
283
+ const geminiSource = path.resolve(__dirname, '..', 'GEMINI.md');
284
+ if (fs.existsSync(geminiSource)) {
285
+ const geminiDest = isGlobal ? path.join(homeDir, '.gemini', 'GEMINI.md') : path.join(cwd, 'GEMINI.md');
286
+ fs.mkdirSync(path.dirname(geminiDest), { recursive: true });
287
+ fs.copyFileSync(geminiSource, geminiDest);
288
+ console.log(` ✅ Copied GEMINI.md → ${geminiDest}`);
289
+ }
290
+ }
291
+ }
292
+
293
+ writeVersionMarker(targetDir);
294
+ console.log(`\n🎉 Hoàn tất v${version}! ${config.note}\n`);
295
+
296
+ } catch (err) {
297
+ console.error('❌ Lỗi cài đặt:', err.message);
298
+ process.exit(1);
299
+ } finally {
300
+ if (rl) rl.close();
301
+ }
302
+ }
303
+
304
+ // ─── CLI entry point ──────────────────────────────────────────────────────────
305
+
306
+ const args = parseArgs();
307
+
308
+ if (args.ide && args.scope) {
309
+ // Non-interactive mode (called via npm scripts)
310
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
311
+ await runInstall(args.ide, args.scope, rl);
312
+ } else {
313
+ // Interactive mode
314
+ console.log(`\n🚀 AI Developer Skill OS v${version} — Setup\n`);
315
+
316
+ const ideQuestion = `Chọn IDE/AI Assistant:
317
+ (1) Antigravity (Google Gemini)
318
+ (2) Claude Code (Anthropic)
319
+ (3) Cursor IDE
320
+ (4) OpenAI Codex CLI
321
+
322
+ Nhập số (1-4): `;
323
+
324
+ const scopeQuestion = `
325
+ Phạm vi cài đặt:
326
+ (1) Local — Chỉ dự án này (.agents/ hoặc .claude/ trong thư mục hiện tại)
327
+ (2) Global — Toàn bộ máy tính (áp dụng cho mọi dự án)
328
+
329
+ Nhập số (1-2): `;
330
+
331
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
332
+
333
+ rl.question(ideQuestion, async (ideAnswer) => {
334
+ rl.question(scopeQuestion, async (scopeAnswer) => {
335
+ await runInstall(ideAnswer.trim(), scopeAnswer.trim(), rl);
336
+ });
337
+ });
338
+ }