@hd-agent-kit/cli 1.0.0 → 1.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  AI agent configuration kit for Claude Code, Cursor, Windsurf, and OpenCode.
4
4
 
5
- Sets up `AGENTS.md` and `.agents/skills/` in your project so AI assistants follow consistent rules and have access to slash commands like `/commit`, `/analyze`, `/refactor`, etc.
5
+ Sets up `AGENTS.md` and skill files in your project so AI assistants follow consistent rules and have access to slash commands like `/commit`, `/analyze`, `/refactor`, etc.
6
6
 
7
7
  ## Installation
8
8
 
@@ -11,8 +11,9 @@ npx @hd-agent-kit/cli init
11
11
  ```
12
12
 
13
13
  This will:
14
- 1. Copy `AGENTS.md` and `.agents/skills/` to your project root
15
- 2. Configure global gitignore so these files don't get pushed to your repo
14
+ 1. Copy `AGENTS.md` to your project root
15
+ 2. Copy skill files to `.claude/skills/` (Claude Code) and `.opencode/skills/` (OpenCode)
16
+ 3. Configure global gitignore so these files don't get pushed to your repo
16
17
 
17
18
  ## Commands
18
19
 
@@ -42,16 +43,23 @@ npx @hd-agent-kit/cli gitignore
42
43
 
43
44
  ```
44
45
  your-project/
45
- ├── AGENTS.md ← Global AI rules
46
- └── .agents/
47
- └── skills/
48
- ├── analyze/SKILL.md ← /analyze — project analysis
49
- ├── commit/SKILL.md ← /commit — smart commits
50
- ├── document/SKILL.md ← /document — documentation
51
- ├── performance-check/SKILL.md ← /performance-check
52
- ├── refactor/SKILL.md ← /refactor — safe refactoring
53
- ├── security-scan/SKILL.md ← /security-scan
54
- └── write-tests/SKILL.md /write-tests — test generation
46
+ ├── AGENTS.md ← Global AI rules (all tools read this)
47
+ ├── .claude/skills/ ← Claude Code skills
48
+ │ ├── analyze/SKILL.md
49
+ ├── commit/SKILL.md
50
+ ├── document/SKILL.md
51
+ ├── performance-check/SKILL.md
52
+ ├── refactor/SKILL.md
53
+ ├── security-scan/SKILL.md
54
+ │ └── write-tests/SKILL.md
55
+ └── .opencode/skills/ OpenCode skills
56
+ ├── analyze/SKILL.md
57
+ ├── commit/SKILL.md
58
+ ├── document/SKILL.md
59
+ ├── performance-check/SKILL.md
60
+ ├── refactor/SKILL.md
61
+ ├── security-scan/SKILL.md
62
+ └── write-tests/SKILL.md
55
63
  ```
56
64
 
57
65
  ## Global Gitignore
@@ -60,7 +68,8 @@ The `init` and `gitignore` commands add these entries to your global gitignore:
60
68
 
61
69
  ```
62
70
  AGENTS.md
63
- .agents/
71
+ .claude/
72
+ .opencode/
64
73
  project-rules.md
65
74
  ```
66
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hd-agent-kit/cli",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "AI agent configuration kit — sets up AGENTS.md and skill files for Claude Code, Cursor, Windsurf, and OpenCode",
5
5
  "bin": {
6
6
  "hd-agent-kit": "./bin/cli.js"
package/src/index.js CHANGED
@@ -4,7 +4,11 @@ const { execSync } = require('child_process');
4
4
  const readline = require('readline');
5
5
 
6
6
  const TEMPLATES_DIR = path.join(__dirname, '..', 'templates');
7
- const GITIGNORE_ENTRIES = ['AGENTS.md', '.agents/', 'project-rules.md'];
7
+ const SKILLS_DIR = path.join(TEMPLATES_DIR, 'skills');
8
+ const GITIGNORE_ENTRIES = ['AGENTS.md', '.claude/', '.opencode/', 'project-rules.md'];
9
+
10
+ // Skill directories for each supported tool
11
+ const SKILL_TARGETS = ['.claude/skills', '.opencode/skills'];
8
12
 
9
13
  // ── Helpers ──────────────────────────────────────────────
10
14
 
@@ -32,6 +36,7 @@ function ask(question) {
32
36
 
33
37
  function getAllFiles(dir, base = dir) {
34
38
  const results = [];
39
+ if (!fs.existsSync(dir)) return results;
35
40
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
36
41
  const fullPath = path.join(dir, entry.name);
37
42
  if (entry.isDirectory()) {
@@ -53,11 +58,9 @@ async function setupGlobalGitignore() {
53
58
  try {
54
59
  gitignorePath = execSync('git config --global core.excludesFile', { encoding: 'utf-8' }).trim();
55
60
  } catch {
56
- // No global gitignore configured yet
57
61
  gitignorePath = '';
58
62
  }
59
63
 
60
- // Resolve ~ to home directory
61
64
  if (gitignorePath.startsWith('~')) {
62
65
  gitignorePath = path.join(process.env.HOME || process.env.USERPROFILE, gitignorePath.slice(1));
63
66
  }
@@ -70,7 +73,6 @@ async function setupGlobalGitignore() {
70
73
  log(`Global gitignore created: ${gitignorePath}`);
71
74
  }
72
75
 
73
- // Read existing content or start fresh
74
76
  let content = '';
75
77
  if (fs.existsSync(gitignorePath)) {
76
78
  content = fs.readFileSync(gitignorePath, 'utf-8');
@@ -98,28 +100,52 @@ async function setupGlobalGitignore() {
98
100
 
99
101
  // ── Copy Files ───────────────────────────────────────────
100
102
 
101
- async function copyFiles(targetDir, { force = false } = {}) {
103
+ function copyFile(src, dest, relLabel, force) {
104
+ const destDir = path.dirname(dest);
105
+ fs.mkdirSync(destDir, { recursive: true });
106
+ fs.copyFileSync(src, dest);
107
+ success(relLabel);
108
+ }
109
+
110
+ async function copyAllFiles(targetDir, { force = false } = {}) {
111
+ // 1) Copy AGENTS.md to project root
102
112
  console.log('\n \uD83D\uDCC1 Copying agent files...\n');
103
113
 
104
- const files = getAllFiles(TEMPLATES_DIR);
114
+ const agentsMdSrc = path.join(TEMPLATES_DIR, 'AGENTS.md');
115
+ const agentsMdDest = path.join(targetDir, 'AGENTS.md');
105
116
 
106
- for (const relPath of files) {
107
- const src = path.join(TEMPLATES_DIR, relPath);
108
- const dest = path.join(targetDir, relPath);
109
- const destDir = path.dirname(dest);
117
+ if (!force && fs.existsSync(agentsMdDest)) {
118
+ const overwrite = await ask('AGENTS.md already exists. Overwrite?');
119
+ if (!overwrite) {
120
+ warn('AGENTS.md skipped');
121
+ } else {
122
+ copyFile(agentsMdSrc, agentsMdDest, 'AGENTS.md', force);
123
+ }
124
+ } else {
125
+ copyFile(agentsMdSrc, agentsMdDest, 'AGENTS.md', force);
126
+ }
110
127
 
111
- // Check if file exists
112
- if (!force && fs.existsSync(dest)) {
113
- const overwrite = await ask(`${relPath} already exists. Overwrite?`);
114
- if (!overwrite) {
115
- warn(`${relPath} skipped`);
116
- continue;
128
+ // 2) Copy skills to each tool's directory
129
+ const skillFiles = getAllFiles(SKILLS_DIR);
130
+
131
+ for (const skillTarget of SKILL_TARGETS) {
132
+ console.log(`\n \uD83D\uDCC2 ${skillTarget}/\n`);
133
+
134
+ for (const relPath of skillFiles) {
135
+ const src = path.join(SKILLS_DIR, relPath);
136
+ const dest = path.join(targetDir, skillTarget, relPath);
137
+ const label = path.join(skillTarget, relPath);
138
+
139
+ if (!force && fs.existsSync(dest)) {
140
+ const overwrite = await ask(`${label} already exists. Overwrite?`);
141
+ if (!overwrite) {
142
+ warn(`${label} skipped`);
143
+ continue;
144
+ }
117
145
  }
118
- }
119
146
 
120
- fs.mkdirSync(destDir, { recursive: true });
121
- fs.copyFileSync(src, dest);
122
- success(relPath);
147
+ copyFile(src, dest, label, force);
148
+ }
123
149
  }
124
150
 
125
151
  console.log('');
@@ -132,7 +158,7 @@ async function init({ force = false } = {}) {
132
158
 
133
159
  const targetDir = process.cwd();
134
160
 
135
- await copyFiles(targetDir, { force });
161
+ await copyAllFiles(targetDir, { force });
136
162
  await setupGlobalGitignore();
137
163
 
138
164
  console.log(' \u2705 Setup complete!\n');
@@ -143,7 +169,7 @@ async function update() {
143
169
 
144
170
  const targetDir = process.cwd();
145
171
 
146
- await copyFiles(targetDir, { force: true });
172
+ await copyAllFiles(targetDir, { force: true });
147
173
 
148
174
  console.log(' \u2705 Update complete!\n');
149
175
  }
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: analyze
3
+ description: Analyze the project structure, tech stack, and conventions to generate project-rules.md
4
+ ---
5
+
1
6
  # /analyze — Proje Analiz Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/analyze`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: commit
3
+ description: Analyze git changes and propose a meaningful commit message following project conventions
4
+ ---
5
+
1
6
  # /commit — Akıllı Commit Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/commit`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: document
3
+ description: Generate JSDoc/TSDoc comments, README, or API documentation for files and modules
4
+ ---
5
+
1
6
  # /document — Dokümantasyon Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/document [dosya/modül/proje]`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: performance-check
3
+ description: Analyze bundle size, render performance, and Core Web Vitals with scored report
4
+ ---
5
+
1
6
  # /performance-check — Performans Analiz Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/performance-check [dosya/modül]`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: refactor
3
+ description: Create a safe step-by-step refactoring plan with impact analysis and risk assessment
4
+ ---
5
+
1
6
  # /refactor — Refactoring Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/refactor [dosya/modül]`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: security-scan
3
+ description: Run dependency audit, detect XSS/CSRF risks, check env variables, and report security issues
4
+ ---
5
+
1
6
  # /security-scan — Güvenlik Tarama Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/security-scan`
@@ -1,3 +1,8 @@
1
+ ---
2
+ name: write-tests
3
+ description: Generate comprehensive test files for components, hooks, and utilities following project conventions
4
+ ---
5
+
1
6
  # /write-tests — Test Yazma Skill'i
2
7
 
3
8
  > **Tetikleyici:** `/write-tests [dosya/modül]`