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