evnict-kit 0.2.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 (138) hide show
  1. package/README.md +19 -0
  2. package/bin/cli.js +38 -0
  3. package/package.json +48 -0
  4. package/src/commands/add.js +129 -0
  5. package/src/commands/init-check.js +19 -0
  6. package/src/commands/init-context.js +37 -0
  7. package/src/commands/init-rules.js +42 -0
  8. package/src/commands/init-workflow.js +36 -0
  9. package/src/commands/init.js +722 -0
  10. package/src/utils/config.js +167 -0
  11. package/src/utils/file.js +53 -0
  12. package/templates/GETTING-STARTED.md +196 -0
  13. package/templates/content/context/AGENTS.md.template +462 -0
  14. package/templates/content/rules/01-evnict-kit-general-rules.md +303 -0
  15. package/templates/content/rules/02-evnict-kit-security-rules.md +423 -0
  16. package/templates/content/rules/03-evnict-kit-backend-conventions.md +383 -0
  17. package/templates/content/rules/04-evnict-kit-frontend-conventions.md +402 -0
  18. package/templates/content/rules/05-evnict-kit-project-conventions.md +228 -0
  19. package/templates/content/skills/evnict-kit-brainstorm/SKILL.md +140 -0
  20. package/templates/content/skills/evnict-kit-bug-fix/SKILL.md +108 -0
  21. package/templates/content/skills/evnict-kit-checkpoint/SKILL.md +156 -0
  22. package/templates/content/skills/evnict-kit-code-review/SKILL.md +158 -0
  23. package/templates/content/skills/evnict-kit-coordinate/SKILL.md +274 -0
  24. package/templates/content/skills/evnict-kit-create-api/SKILL.md +281 -0
  25. package/templates/content/skills/evnict-kit-create-component/SKILL.md +263 -0
  26. package/templates/content/skills/evnict-kit-create-page/SKILL.md +247 -0
  27. package/templates/content/skills/evnict-kit-database-migration/SKILL.md +164 -0
  28. package/templates/content/skills/evnict-kit-doc-postmortem/SKILL.md +93 -0
  29. package/templates/content/skills/evnict-kit-finish-branch/SKILL.md +87 -0
  30. package/templates/content/skills/evnict-kit-fix-attt/SKILL.md +129 -0
  31. package/templates/content/skills/evnict-kit-fix-business-logic/SKILL.md +89 -0
  32. package/templates/content/skills/evnict-kit-git-worktrees/SKILL.md +104 -0
  33. package/templates/content/skills/evnict-kit-merge-checklist/SKILL.md +108 -0
  34. package/templates/content/skills/evnict-kit-onboard/SKILL.md +143 -0
  35. package/templates/content/skills/evnict-kit-prompt-standard/SKILL.md +103 -0
  36. package/templates/content/skills/evnict-kit-receiving-review/SKILL.md +89 -0
  37. package/templates/content/skills/evnict-kit-security-audit/SKILL.md +190 -0
  38. package/templates/content/skills/evnict-kit-spec/SKILL.md +237 -0
  39. package/templates/content/skills/evnict-kit-tdd/SKILL.md +413 -0
  40. package/templates/content/skills/evnict-kit-wiki/SKILL.md +412 -0
  41. package/templates/content/workflows/evnict-kit-archive-wiki.md +100 -0
  42. package/templates/content/workflows/evnict-kit-attt.md +100 -0
  43. package/templates/content/workflows/evnict-kit-bug-fix.md +107 -0
  44. package/templates/content/workflows/evnict-kit-feature-large.md +393 -0
  45. package/templates/content/workflows/evnict-kit-feature-small.md +86 -0
  46. package/templates/content/workflows/evnict-kit-handoff.md +243 -0
  47. package/templates/content/workflows/evnict-kit-implement.md +247 -0
  48. package/templates/content/workflows/evnict-kit-init-check.md +76 -0
  49. package/templates/content/workflows/evnict-kit-init-context.md +58 -0
  50. package/templates/content/workflows/evnict-kit-init-rules.md +114 -0
  51. package/templates/content/workflows/evnict-kit-init-wiki.md +80 -0
  52. package/templates/content/workflows/evnict-kit-plan.md +308 -0
  53. package/templates/content/workflows/evnict-kit-review.md +53 -0
  54. package/templates/content/workflows/evnict-kit-spec-archive.md +53 -0
  55. package/templates/content/workflows/evnict-kit-wiki-archive-feature.md +164 -0
  56. package/templates/content/workflows/evnict-kit-wiki-query.md +91 -0
  57. package/templates/content/workflows/evnict-kit-wiki-scan-project.md +272 -0
  58. package/templates/context/AGENT.md.template +9 -0
  59. package/templates/context/AGENTS.md.template +462 -0
  60. package/templates/context/CLAUDE.md.template +301 -0
  61. package/templates/context/copilot-instructions.md.template +60 -0
  62. package/templates/context/cursorrules.template +114 -0
  63. package/templates/instruct/Instruct-Agent-AI.be.md +96 -0
  64. package/templates/instruct/Instruct-Agent-AI.fe.md +79 -0
  65. package/templates/rules/antigravity/01-evnict-kit-general-rules.md +303 -0
  66. package/templates/rules/antigravity/02-evnict-kit-security-rules.md +423 -0
  67. package/templates/rules/antigravity/03-evnict-kit-backend-conventions.md +383 -0
  68. package/templates/rules/antigravity/04-evnict-kit-frontend-conventions.md +402 -0
  69. package/templates/rules/antigravity/05-evnict-kit-project-conventions.md +228 -0
  70. package/templates/rules/claude/README.md +8 -0
  71. package/templates/rules/cursor/01-evnict-kit-general-rules.mdc +46 -0
  72. package/templates/rules/cursor/02-evnict-kit-security-rules.mdc +46 -0
  73. package/templates/rules/cursor/03-evnict-kit-backend-conventions.mdc +50 -0
  74. package/templates/rules/cursor/04-evnict-kit-frontend-conventions.mdc +43 -0
  75. package/templates/rules/cursor/05-evnict-kit-project-conventions.mdc +63 -0
  76. package/templates/rules/cursor/README.md +7 -0
  77. package/templates/skills/evnict-kit-brainstorm/SKILL.md +140 -0
  78. package/templates/skills/evnict-kit-bug-fix/SKILL.md +108 -0
  79. package/templates/skills/evnict-kit-checkpoint/SKILL.md +156 -0
  80. package/templates/skills/evnict-kit-code-review/SKILL.md +158 -0
  81. package/templates/skills/evnict-kit-coordinate/SKILL.md +274 -0
  82. package/templates/skills/evnict-kit-create-api/SKILL.md +281 -0
  83. package/templates/skills/evnict-kit-create-component/SKILL.md +263 -0
  84. package/templates/skills/evnict-kit-create-page/SKILL.md +247 -0
  85. package/templates/skills/evnict-kit-database-migration/SKILL.md +164 -0
  86. package/templates/skills/evnict-kit-doc-postmortem/SKILL.md +93 -0
  87. package/templates/skills/evnict-kit-finish-branch/SKILL.md +87 -0
  88. package/templates/skills/evnict-kit-fix-attt/SKILL.md +129 -0
  89. package/templates/skills/evnict-kit-fix-business-logic/SKILL.md +89 -0
  90. package/templates/skills/evnict-kit-git-worktrees/SKILL.md +104 -0
  91. package/templates/skills/evnict-kit-merge-checklist/SKILL.md +108 -0
  92. package/templates/skills/evnict-kit-onboard/SKILL.md +143 -0
  93. package/templates/skills/evnict-kit-prompt-standard/SKILL.md +103 -0
  94. package/templates/skills/evnict-kit-receiving-review/SKILL.md +89 -0
  95. package/templates/skills/evnict-kit-security-audit/SKILL.md +190 -0
  96. package/templates/skills/evnict-kit-spec/SKILL.md +237 -0
  97. package/templates/skills/evnict-kit-tdd/SKILL.md +413 -0
  98. package/templates/skills/evnict-kit-wiki/SKILL.md +412 -0
  99. package/templates/wiki/README.md +35 -0
  100. package/templates/wiki/config.example.yaml +17 -0
  101. package/templates/wiki/package.json +17 -0
  102. package/templates/wiki/raw/notes/.gitkeep +1 -0
  103. package/templates/wiki/scripts/ingest.js +66 -0
  104. package/templates/workflows/antigravity/evnict-kit-archive-wiki.md +100 -0
  105. package/templates/workflows/antigravity/evnict-kit-attt.md +100 -0
  106. package/templates/workflows/antigravity/evnict-kit-bug-fix.md +107 -0
  107. package/templates/workflows/antigravity/evnict-kit-feature-large.md +393 -0
  108. package/templates/workflows/antigravity/evnict-kit-feature-small.md +86 -0
  109. package/templates/workflows/antigravity/evnict-kit-handoff.md +243 -0
  110. package/templates/workflows/antigravity/evnict-kit-implement.md +247 -0
  111. package/templates/workflows/antigravity/evnict-kit-init-check.md +76 -0
  112. package/templates/workflows/antigravity/evnict-kit-init-context.md +58 -0
  113. package/templates/workflows/antigravity/evnict-kit-init-rules.md +114 -0
  114. package/templates/workflows/antigravity/evnict-kit-init-wiki.md +80 -0
  115. package/templates/workflows/antigravity/evnict-kit-plan.md +308 -0
  116. package/templates/workflows/antigravity/evnict-kit-review.md +53 -0
  117. package/templates/workflows/antigravity/evnict-kit-spec-archive.md +53 -0
  118. package/templates/workflows/antigravity/evnict-kit-wiki-archive-feature.md +164 -0
  119. package/templates/workflows/antigravity/evnict-kit-wiki-query.md +91 -0
  120. package/templates/workflows/antigravity/evnict-kit-wiki-scan-project.md +272 -0
  121. package/templates/workflows/claude/README.md +6 -0
  122. package/templates/workflows/claude/evnict-kit-archive-wiki.md +98 -0
  123. package/templates/workflows/claude/evnict-kit-attt.md +98 -0
  124. package/templates/workflows/claude/evnict-kit-bug-fix.md +105 -0
  125. package/templates/workflows/claude/evnict-kit-feature-large.md +391 -0
  126. package/templates/workflows/claude/evnict-kit-feature-small.md +84 -0
  127. package/templates/workflows/claude/evnict-kit-handoff.md +240 -0
  128. package/templates/workflows/claude/evnict-kit-implement.md +245 -0
  129. package/templates/workflows/claude/evnict-kit-init-check.md +74 -0
  130. package/templates/workflows/claude/evnict-kit-init-context.md +56 -0
  131. package/templates/workflows/claude/evnict-kit-init-rules.md +112 -0
  132. package/templates/workflows/claude/evnict-kit-init-wiki.md +78 -0
  133. package/templates/workflows/claude/evnict-kit-plan.md +305 -0
  134. package/templates/workflows/claude/evnict-kit-review.md +51 -0
  135. package/templates/workflows/claude/evnict-kit-spec-archive.md +51 -0
  136. package/templates/workflows/claude/evnict-kit-wiki-archive-feature.md +162 -0
  137. package/templates/workflows/claude/evnict-kit-wiki-query.md +89 -0
  138. package/templates/workflows/claude/evnict-kit-wiki-scan-project.md +270 -0
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # EVNICT-KIT v0.1.2
2
+
3
+ > Bộ công cụ hỗ trợ PTPM với AI — theo QĐ-TTPM
4
+ > Tích hợp OpenSpec (SDD) + TDD Workflow + LLM Wiki
5
+
6
+ ## Quick Start
7
+
8
+ ```bash
9
+ npm install -g evnict-kit
10
+ cd /path/to/workspace # chứa cmis-be/ và cmis-fe/
11
+ evnict-kit init --name=cmis --be=cmis-be --fe=cmis-fe
12
+ ```
13
+
14
+ Mở AI Agent trong cmis-be/ → chạy: /evnict-kit:init-rules
15
+
16
+ ## Multi-tool: --tool=antigravity|claude|cursor|copilot|codex
17
+
18
+ ## Stats: 35 rules | 20 skills | 10 workflows
19
+ ## License: UNLICENSED (EVNICT internal)
package/bin/cli.js ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { initCommand } from '../src/commands/init.js';
4
+ import { addCommand } from '../src/commands/add.js';
5
+ import { initRulesCommand } from '../src/commands/init-rules.js';
6
+ import { initContextCommand } from '../src/commands/init-context.js';
7
+ import { initWorkflowCommand } from '../src/commands/init-workflow.js';
8
+ import { initCheckCommand } from '../src/commands/init-check.js';
9
+
10
+ const program = new Command();
11
+ program.name('evnict-kit').description('EVNICT AI-Assisted Development Toolkit v0.2.1').version('0.2.1');
12
+
13
+ program.command('init')
14
+ .description('Khởi tạo workspace + deploy rules/skills/workflows vào từng project (interactive hoặc flags)')
15
+ .option('--name <n>', 'Tên dự án (nếu bỏ qua → interactive wizard)')
16
+ .option('--be <folder>', 'Folder backend (default: <n>-be)')
17
+ .option('--fe <folder>', 'Folder frontend (default: <n>-fe)')
18
+ .option('--tool <tool>', 'AI tool: antigravity|claude|cursor|copilot|codex', 'antigravity')
19
+ .option('--tech-be <tech>', 'springboot|aspnet|javaee', 'springboot')
20
+ .option('--tech-fe <tech>', 'angular|react-web|react-mobile', 'angular')
21
+ .option('--db <db>', 'oracle|sqlserver', 'oracle')
22
+ .option('--no-wiki', 'Không setup wiki')
23
+ .option('--no-interactive', 'Bắt buộc chạy non-interactive (cần --name)')
24
+ .action(initCommand);
25
+
26
+ program.command('add <folder>')
27
+ .description('Thêm 1 project vào workspace đã init (deploy rules/skills/workflows + symlinks)')
28
+ .option('--type <type>', 'backend|frontend')
29
+ .option('--tech <tech>', 'springboot|angular|react-web|react-mobile|aspnet')
30
+ .option('--tool <tool>', 'AI tool override')
31
+ .action(addCommand);
32
+
33
+ program.command('init-rules').description('Scaffold rules vào từng project (theo --tool)').option('--tool <tool>','','antigravity').action(initRulesCommand);
34
+ program.command('init-context').description('Scaffold context files vào từng project').option('--tool <tool>','','antigravity').action(initContextCommand);
35
+ program.command('init-workflow').description('Scaffold workflows & skills vào từng project').option('--tool <tool>','','antigravity').action(initWorkflowCommand);
36
+ program.command('init-check').description('Chuẩn bị demo-check directory').option('--tool <tool>','','antigravity').action(initCheckCommand);
37
+
38
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "evnict-kit",
3
+ "version": "0.2.1",
4
+ "description": "EVNICT AI-Assisted Development Toolkit - Bộ công cụ hỗ trợ phát triển phần mềm với AI theo quy định QĐ-TTPM",
5
+ "type": "module",
6
+ "bin": {
7
+ "evnict-kit": "./bin/cli.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/",
12
+ "templates/",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "test": "node test/test.js",
17
+ "link": "npm link"
18
+ },
19
+ "dependencies": {
20
+ "commander": "^12.1.0",
21
+ "js-yaml": "^4.1.0"
22
+ },
23
+ "keywords": [
24
+ "evnict",
25
+ "evn",
26
+ "ai",
27
+ "development",
28
+ "toolkit",
29
+ "coding-agent"
30
+ ],
31
+ "author": "EVNICT - Trung tâm Phát triển Phần mềm",
32
+ "thirdPartyLicenses": {
33
+ "llm-wiki": {
34
+ "version": "1.0.0",
35
+ "license": "MIT",
36
+ "repository": "https://github.com/mduongvandinh/llm-wiki",
37
+ "note": "Minimal scaffold bundled in templates/wiki/"
38
+ }
39
+ },
40
+ "license": "UNLICENSED",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/NhanVAT/evnict-kit"
44
+ },
45
+ "engines": {
46
+ "node": ">=18.0.0"
47
+ }
48
+ }
@@ -0,0 +1,129 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import readline from 'node:readline';
4
+ import yaml from 'js-yaml';
5
+ import { deployToProject, createSymlinks, updateGitignore, detectTech } from './init.js';
6
+ import { loadConfig, getToolMap, TECH_LABELS, TECH_TYPE_HINTS, SUPPORTED_TOOLS } from '../utils/config.js';
7
+
8
+ /**
9
+ * evnict-kit add <folder>
10
+ * Thêm 1 project vào workspace đã init — deploy rules/skills/workflows + tạo symlinks
11
+ */
12
+ export async function addCommand(folder, options) {
13
+ const cwd = process.cwd();
14
+
15
+ // Load existing config
16
+ const config = loadConfig(cwd);
17
+ if (!config) {
18
+ console.error('❌ Không tìm thấy .evnict/config.yaml. Chạy evnict-kit init trước.');
19
+ process.exit(1);
20
+ }
21
+
22
+ const name = config.project?.name;
23
+ if (!name) {
24
+ console.error('❌ config.yaml thiếu project.name.');
25
+ process.exit(1);
26
+ }
27
+
28
+ // Check if folder exists
29
+ const projectPath = join(cwd, folder);
30
+ if (!existsSync(projectPath)) {
31
+ console.error(`❌ Folder "${folder}" không tồn tại trong workspace.`);
32
+ process.exit(1);
33
+ }
34
+
35
+ // Check if already in config
36
+ const existing = config.repos?.find(r => r.folder === folder);
37
+ if (existing) {
38
+ console.log(`⚠️ "${folder}" đã có trong config.yaml (type: ${existing.type}). Deploy lại...`);
39
+ }
40
+
41
+ // Detect tech
42
+ const detectedTech = detectTech(projectPath);
43
+ const techLabel = detectedTech ? TECH_LABELS[detectedTech] || detectedTech : 'unknown';
44
+ console.log(`\n📂 Folder: ${folder} (detected: ${techLabel})`);
45
+
46
+ // Determine type and tech
47
+ let type = options.type;
48
+ let tech = options.tech || detectedTech;
49
+ const tool = options.tool || config.ai_tool || 'antigravity';
50
+
51
+ if (!SUPPORTED_TOOLS.includes(tool)) {
52
+ console.error(`❌ Tool "${tool}" chưa có templates.`);
53
+ process.exit(1);
54
+ }
55
+
56
+ // If type/tech not provided via flags, ask interactively
57
+ if (!type) {
58
+ const suggestedType = detectedTech ? (TECH_TYPE_HINTS[detectedTech] || 'backend') : 'backend';
59
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
60
+ const ask = (q) => new Promise(r => rl.question(q, r));
61
+
62
+ const typeInput = (await ask(`? Loại cho ${folder} (${techLabel}) [${suggestedType}]: `)).trim();
63
+ type = typeInput || suggestedType;
64
+
65
+ if (!tech) {
66
+ const defaultTech = type === 'backend' ? 'springboot' : 'angular';
67
+ const techInput = (await ask(`? Tech stack [${defaultTech}]: `)).trim();
68
+ tech = techInput || defaultTech;
69
+ }
70
+
71
+ rl.close();
72
+ }
73
+
74
+ type = type || 'backend';
75
+ tech = tech || (type === 'backend' ? 'springboot' : 'angular');
76
+ const db = config.database?.type || 'oracle';
77
+ const toolMap = getToolMap(tool);
78
+
79
+ console.log(`\n🚀 Deploying evnict-kit vào ${folder} (${type}/${TECH_LABELS[tech] || tech})...\n`);
80
+
81
+ // Build allRepos (existing + new)
82
+ const allRepos = [...(config.repos || [])];
83
+ if (!existing) {
84
+ allRepos.push({ folder, type, tech });
85
+ }
86
+
87
+ // Deploy
88
+ deployToProject(projectPath, cwd, {
89
+ tool, toolMap, name, type, tech, db,
90
+ allRepos,
91
+ });
92
+
93
+ // Symlinks
94
+ createSymlinks(projectPath, cwd, name);
95
+
96
+ // Update .gitignore
97
+ updateGitignore(projectPath, name);
98
+
99
+ // Update config.yaml — add new repo
100
+ if (!existing) {
101
+ const configPath = join(cwd, '.evnict', 'config.yaml');
102
+ const rawConfig = yaml.load(readFileSync(configPath, 'utf8'));
103
+
104
+ // Ensure repos is array (migration)
105
+ if (!Array.isArray(rawConfig.repos)) {
106
+ // Convert old format
107
+ const repos = [];
108
+ if (rawConfig.repos?.backend) repos.push({ folder: rawConfig.repos.backend.folder, type: 'backend', tech: rawConfig.repos.backend.tech });
109
+ if (rawConfig.repos?.frontend) repos.push({ folder: rawConfig.repos.frontend.folder, type: 'frontend', tech: rawConfig.repos.frontend.tech });
110
+ rawConfig.repos = repos;
111
+ }
112
+
113
+ rawConfig.repos.push({ folder, type, tech });
114
+ writeFileSync(configPath, yaml.dump(rawConfig, { lineWidth: -1 }), 'utf8');
115
+ console.log(`\n ✅ config.yaml updated — added ${folder}`);
116
+ }
117
+
118
+ console.log(`
119
+ ╔═══════════════════════════════════════════════════════╗
120
+ ║ ✅ "${folder}" added to workspace "${name}"! ║
121
+ ╠═══════════════════════════════════════════════════════╣
122
+ ║ ║
123
+ ║ 📋 Next: Mở AI Agent trong ${folder}/ ║
124
+ ║ /evnict-kit:init-rules → điền rules ║
125
+ ║ /evnict-kit:init-context → sinh context file ║
126
+ ║ ║
127
+ ╚═══════════════════════════════════════════════════════╝
128
+ `);
129
+ }
@@ -0,0 +1,19 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { ensureDir, writeFile } from '../utils/file.js';
4
+ import { mergeWithConfig, getToolMap } from '../utils/config.js';
5
+
6
+ export async function initCheckCommand(options) {
7
+ const cwd = process.cwd();
8
+ const opts = mergeWithConfig(options, cwd);
9
+ const toolMap = getToolMap(opts.tool || 'antigravity');
10
+
11
+ console.log('\n🔍 EVNICT-KIT v0.1.2: Init Check\n');
12
+ const projects = [opts.be, opts.fe].filter(f => f && existsSync(join(cwd, f)));
13
+ for (const folder of projects) {
14
+ const checkDir = join(cwd, folder, toolMap.agentDir, 'demo-check');
15
+ ensureDir(checkDir, cwd);
16
+ writeFile(join(checkDir, 'REVIEW.md'), `# Demo Check — ${folder}\nChạy /evnict-kit:init-check trong Agent để sinh demo code.\n\n## Checklist\n- [ ] Naming convention đúng?\n- [ ] Package structure đúng?\n- [ ] API format đúng?\n- [ ] Error handling đúng?\n- [ ] Test pattern đúng?\n`, { cwd, overwrite: true });
17
+ }
18
+ console.log('\n✅ Demo-check prepared. Mở Agent → /evnict-kit:init-check\n');
19
+ }
@@ -0,0 +1,37 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { ensureDir, writeFile, TEMPLATES_DIR } from '../utils/file.js';
4
+ import { mergeWithConfig, getToolMap, TECH_LABELS } from '../utils/config.js';
5
+
6
+ export async function initContextCommand(options) {
7
+ const cwd = process.cwd();
8
+ const opts = mergeWithConfig(options, cwd);
9
+ const tool = opts.tool || 'antigravity';
10
+ const toolMap = getToolMap(tool);
11
+
12
+ console.log(`\n📋 EVNICT-KIT v0.1.2: Scaffold Context (tool: ${tool})\n`);
13
+
14
+ const evnictDir = join(cwd, '.evnict');
15
+ if (!existsSync(evnictDir)) { console.error('❌ Chạy "evnict-kit init" trước.'); process.exit(1); }
16
+
17
+ const ctxMap = { antigravity:'AGENT.md.template', claude:'CLAUDE.md.template', cursor:'cursorrules.template', copilot:'AGENT.md.template', codex:'AGENT.md.template' };
18
+ const projects = [
19
+ { folder: opts.be, tech: opts.techBe, type: 'backend' },
20
+ { folder: opts.fe, tech: opts.techFe, type: 'frontend' },
21
+ ];
22
+
23
+ for (const { folder, tech, type } of projects) {
24
+ if (!folder || !existsSync(join(cwd, folder))) continue;
25
+ console.log(`── ${folder} ──`);
26
+ const tplPath = join(TEMPLATES_DIR, 'context', ctxMap[tool]);
27
+ if (existsSync(tplPath)) {
28
+ let content = readFileSync(tplPath, 'utf8')
29
+ .replaceAll('{{PROJECT_NAME}}', opts.name || '')
30
+ .replaceAll('{{TECH_STACK}}', TECH_LABELS[tech] || tech)
31
+ .replaceAll('{{DATABASE}}', TECH_LABELS[opts.db] || opts.db || '');
32
+ writeFile(join(cwd, folder, toolMap.contextFile), content, { cwd });
33
+ }
34
+ ensureDir(join(cwd, folder, toolMap.contextDir), cwd);
35
+ }
36
+ console.log('\n✅ Context scaffolded. Next: mở Agent → /evnict-kit:init-context\n');
37
+ }
@@ -0,0 +1,42 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { ensureDir, copyTemplateDir, writeFile, TEMPLATES_DIR } from '../utils/file.js';
4
+ import { mergeWithConfig, getToolMap } from '../utils/config.js';
5
+
6
+ export async function initRulesCommand(options) {
7
+ const cwd = process.cwd();
8
+ const opts = mergeWithConfig(options, cwd);
9
+ const tool = opts.tool || 'antigravity';
10
+ const toolMap = getToolMap(tool);
11
+
12
+ console.log(`\n📏 EVNICT-KIT v0.1.2: Scaffold Rules (tool: ${tool})\n`);
13
+
14
+ // Detect if we're inside a project or workspace
15
+ const evnictDir = join(cwd, '.evnict');
16
+ if (!existsSync(evnictDir)) {
17
+ console.error('❌ Chưa init workspace. Chạy "evnict-kit init" trước.');
18
+ process.exit(1);
19
+ }
20
+
21
+ // Read config to find project folders
22
+ const config = opts;
23
+ const projects = [];
24
+ if (config.be && existsSync(join(cwd, config.be))) projects.push({ folder: config.be, cats: ['common','backend','security','project'] });
25
+ if (config.fe && existsSync(join(cwd, config.fe))) projects.push({ folder: config.fe, cats: ['common','frontend','security','project'] });
26
+
27
+ for (const { folder, cats } of projects) {
28
+ console.log(`\n── ${folder} ──`);
29
+ for (const cat of cats) {
30
+ const src = join(TEMPLATES_DIR, 'rules', cat);
31
+ const dest = join(cwd, folder, toolMap.rulesDir, cat);
32
+ if (existsSync(src)) {
33
+ ensureDir(dest, cwd);
34
+ copyTemplateDir(src, dest, cwd);
35
+ }
36
+ }
37
+ const idxSrc = join(TEMPLATES_DIR, 'rules', 'INDEX.md');
38
+ if (existsSync(idxSrc)) writeFile(join(cwd, folder, toolMap.rulesDir, 'INDEX.md'), readFileSync(idxSrc,'utf8'), {cwd, overwrite:true});
39
+ }
40
+
41
+ console.log('\n✅ Rules deployed. Next: mở Agent → /evnict-kit:init-rules\n');
42
+ }
@@ -0,0 +1,36 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { ensureDir, copyTemplateDir, TEMPLATES_DIR } from '../utils/file.js';
4
+ import { mergeWithConfig, getToolMap } from '../utils/config.js';
5
+
6
+ export async function initWorkflowCommand(options) {
7
+ const cwd = process.cwd();
8
+ const opts = mergeWithConfig(options, cwd);
9
+ const tool = opts.tool || 'antigravity';
10
+ const toolMap = getToolMap(tool);
11
+
12
+ console.log(`\n🔄 EVNICT-KIT v0.1.2: Scaffold Workflows & Skills (tool: ${tool})\n`);
13
+
14
+ const projects = [opts.be, opts.fe].filter(f => f && existsSync(join(cwd, f)));
15
+ for (const folder of projects) {
16
+ console.log(`── ${folder} ──`);
17
+ // Workflows
18
+ for (const cat of ['init','work']) {
19
+ const src = join(TEMPLATES_DIR, 'workflows', cat);
20
+ const dest = join(cwd, folder, toolMap.workflowsDir, cat);
21
+ if (existsSync(src)) { ensureDir(dest,cwd); copyTemplateDir(src,dest,cwd); }
22
+ }
23
+ // Skills
24
+ const skillsSrc = join(TEMPLATES_DIR, 'skills');
25
+ if (existsSync(skillsSrc)) {
26
+ for (const d of readdirSync(skillsSrc, {withFileTypes:true})) {
27
+ if (d.isDirectory()) {
28
+ const dest = join(cwd, folder, toolMap.skillsDir, d.name);
29
+ ensureDir(dest,cwd);
30
+ copyTemplateDir(join(skillsSrc,d.name), dest, cwd);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ console.log('\n✅ Workflows + Skills deployed.\n');
36
+ }