@kurokeita/add-skill 1.11.0 → 1.13.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
@@ -87,6 +87,7 @@ pnpm dev import https://github.com/owner/repo/tree/main/skills/skill-name
87
87
  | Platform | Agents Path | Skills Path | Workflows Path |
88
88
  | :--- | :--- | :--- | :--- |
89
89
  | Antigravity | *Not Supported* | `~/.gemini/antigravity/global_skills` | `~/.gemini/antigravity/global_workflows` |
90
+ | Claude Code | `~/.claude/agents` | `~/.claude/skills` | `~/.claude/skills` |
90
91
  | Codex | `~/.codex/skills` | `~/.codex/skills` | `~/.codex/skills` |
91
92
  | Gemini CLI | `~/.gemini/agents` | `~/.gemini/skills` | `~/.gemini/commands` |
92
93
  | GitHub Copilot | `~/.copilot/agents` | `~/.copilot/skills` | `~/.copilot/prompts` |
package/dist/bin/cli.js CHANGED
@@ -7,7 +7,7 @@ import pc5 from "picocolors";
7
7
 
8
8
  // src/commands/add.ts
9
9
  import os3 from "node:os";
10
- import path5 from "node:path";
10
+ import path6 from "node:path";
11
11
  import {
12
12
  cancel,
13
13
  confirm,
@@ -119,6 +119,7 @@ function resolveProjectRoot(moduleDir) {
119
119
  var PROJECT_ROOT = resolveProjectRoot(__dirname);
120
120
  var PLATFORM_LABELS = {
121
121
  antigravity: "Antigravity",
122
+ "claude-code": "Claude Code",
122
123
  codex: "Codex",
123
124
  gemini: "Gemini CLI",
124
125
  copilot: "GitHub Copilot",
@@ -126,18 +127,21 @@ var PLATFORM_LABELS = {
126
127
  };
127
128
  var PLATFORM_PATHS_SKILLS = {
128
129
  antigravity: path2.join(os2.homedir(), ".gemini/antigravity/global_skills"),
130
+ "claude-code": path2.join(os2.homedir(), ".claude/skills"),
129
131
  codex: path2.join(os2.homedir(), ".codex/skills"),
130
132
  copilot: path2.join(os2.homedir(), ".copilot/skills"),
131
133
  gemini: path2.join(os2.homedir(), ".gemini/skills"),
132
134
  windsurf: path2.join(os2.homedir(), ".codeium/windsurf/skills")
133
135
  };
134
136
  var PLATFORM_PATHS_AGENTS = {
137
+ "claude-code": path2.join(os2.homedir(), ".claude/agents"),
135
138
  codex: path2.join(os2.homedir(), ".codex/skills"),
136
139
  copilot: path2.join(os2.homedir(), ".copilot/agents"),
137
140
  gemini: path2.join(os2.homedir(), ".gemini/agents")
138
141
  };
139
142
  var PLATFORM_PATHS_WORKFLOWS = {
140
143
  antigravity: path2.join(os2.homedir(), ".gemini/antigravity/global_workflows"),
144
+ "claude-code": path2.join(os2.homedir(), ".claude/skills"),
141
145
  codex: path2.join(os2.homedir(), ".codex/skills"),
142
146
  copilot: path2.join(os2.homedir(), ".copilot/prompts"),
143
147
  gemini: path2.join(os2.homedir(), ".gemini/commands"),
@@ -170,11 +174,106 @@ var AntigravityHandler = class {
170
174
  }
171
175
  };
172
176
 
173
- // src/utils/platforms/codex.ts
177
+ // src/utils/platforms/claude-code.ts
174
178
  import path3 from "node:path";
175
- import fs3 from "fs-extra";
176
179
  import yaml from "js-yaml";
177
180
  var frontmatterRegex = /^---\n([\s\S]*?)\n---/;
181
+ var CLAUDE_CODE_TOOLS = [
182
+ "Read",
183
+ "Edit",
184
+ "Write",
185
+ "Bash",
186
+ "Glob",
187
+ "Grep",
188
+ "WebFetch",
189
+ "WebSearch"
190
+ ];
191
+ var ClaudeCodeHandler = class {
192
+ platform = "claude-code";
193
+ getTargetFileName(itemName, type) {
194
+ if (type === "agent") {
195
+ const name = itemName.replace(/\.md$/, "");
196
+ return path3.join(name, `${name}.md`);
197
+ }
198
+ if (type === "workflow") {
199
+ const name = itemName.replace(/\.md$/, "");
200
+ return path3.join(name, "SKILL.md");
201
+ }
202
+ return itemName;
203
+ }
204
+ transform(content, type, itemName) {
205
+ if (type === "skill") return content;
206
+ if (type === "agent") {
207
+ return this.transformAgent(content, itemName);
208
+ }
209
+ if (type === "workflow") {
210
+ return this.transformWorkflow(content, itemName);
211
+ }
212
+ return content;
213
+ }
214
+ transformAgent(content, itemName) {
215
+ const match = content.match(frontmatterRegex);
216
+ let frontmatter = {
217
+ name: itemName.replace(/\.md$/, ""),
218
+ description: "",
219
+ tools: CLAUDE_CODE_TOOLS
220
+ };
221
+ let body = content;
222
+ if (match) {
223
+ try {
224
+ const parsed = yaml.load(match[1]);
225
+ frontmatter = { ...frontmatter, ...parsed };
226
+ frontmatter.tools = CLAUDE_CODE_TOOLS;
227
+ delete frontmatter.target;
228
+ body = content.replace(frontmatterRegex, "").trim();
229
+ } catch (_) {
230
+ }
231
+ }
232
+ const yamlStr = yaml.dump(frontmatter);
233
+ return `---
234
+ ${yamlStr}---
235
+
236
+ ${body}`;
237
+ }
238
+ transformWorkflow(content, itemName) {
239
+ const name = itemName.replace(/\.md$/, "");
240
+ const match = content.match(frontmatterRegex);
241
+ let description = "";
242
+ let body = content.trim();
243
+ if (match) {
244
+ try {
245
+ const parsed = yaml.load(match[1]);
246
+ if (typeof parsed.description === "string" && parsed.description.trim()) {
247
+ description = parsed.description.trim();
248
+ }
249
+ if (typeof parsed.name === "string" && parsed.name.trim()) {
250
+ }
251
+ } catch (_) {
252
+ }
253
+ body = content.replace(frontmatterRegex, "").trim();
254
+ }
255
+ if (!description) {
256
+ const titleMatch = body.match(/^#\s+(.+)$/m);
257
+ const title = titleMatch?.[1]?.trim() || name;
258
+ description = `Workflow: ${title}`;
259
+ }
260
+ const frontmatter = yaml.dump({
261
+ name,
262
+ description,
263
+ "user-invocable": true
264
+ });
265
+ return `---
266
+ ${frontmatter}---
267
+
268
+ ${body}`;
269
+ }
270
+ };
271
+
272
+ // src/utils/platforms/codex.ts
273
+ import path4 from "node:path";
274
+ import fs3 from "fs-extra";
275
+ import yaml2 from "js-yaml";
276
+ var frontmatterRegex2 = /^---\n([\s\S]*?)\n---/;
178
277
  var CODEX_TYPE_FIELD = "x-ai-agents-type";
179
278
  function extractTitle(body) {
180
279
  const match = body.match(/^#\s+(.+)$/m);
@@ -193,7 +292,7 @@ function buildDescription(type, itemName, title) {
193
292
  function toYamlFrontmatter(name, description, extraFields = {}) {
194
293
  const normalizedName = name.replace(/\n+/g, " ").trim();
195
294
  const normalizedDescription = description.replace(/\n+/g, " ").trim();
196
- return yaml.dump(
295
+ return yaml2.dump(
197
296
  {
198
297
  name: normalizedName,
199
298
  description: normalizedDescription,
@@ -203,10 +302,10 @@ function toYamlFrontmatter(name, description, extraFields = {}) {
203
302
  ).trimEnd();
204
303
  }
205
304
  function parseCodexType(content) {
206
- const match = content.match(frontmatterRegex);
305
+ const match = content.match(frontmatterRegex2);
207
306
  if (!match) return "skill";
208
307
  try {
209
- const parsed = yaml.load(match[1]);
308
+ const parsed = yaml2.load(match[1]);
210
309
  if (parsed && typeof parsed === "object") {
211
310
  const type = parsed[CODEX_TYPE_FIELD];
212
311
  if (type === "agent" || type === "workflow" || type === "skill") {
@@ -221,9 +320,9 @@ function parseCodexType(content) {
221
320
  async function codexEntryMatchesType(basePath, entry, requestedType) {
222
321
  let targetPath = null;
223
322
  if (entry.isDirectory()) {
224
- targetPath = path3.join(basePath, entry.name, "SKILL.md");
323
+ targetPath = path4.join(basePath, entry.name, "SKILL.md");
225
324
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
226
- targetPath = path3.join(basePath, entry.name);
325
+ targetPath = path4.join(basePath, entry.name);
227
326
  }
228
327
  if (!targetPath) return false;
229
328
  try {
@@ -237,7 +336,7 @@ var CodexHandler = class {
237
336
  platform = "codex";
238
337
  getTargetFileName(itemName, type) {
239
338
  if (type === "agent" || type === "workflow") {
240
- return path3.join(path3.parse(itemName).name, "SKILL.md");
339
+ return path4.join(path4.parse(itemName).name, "SKILL.md");
241
340
  }
242
341
  return itemName;
243
342
  }
@@ -247,11 +346,11 @@ var CodexHandler = class {
247
346
  let name = itemName;
248
347
  let description = "";
249
348
  let body = content.trim();
250
- const match = content.match(frontmatterRegex);
349
+ const match = content.match(frontmatterRegex2);
251
350
  if (match) {
252
- body = content.replace(frontmatterRegex, "").trim();
351
+ body = content.replace(frontmatterRegex2, "").trim();
253
352
  try {
254
- const parsed = yaml.load(match[1]);
353
+ const parsed = yaml2.load(match[1]);
255
354
  if (parsed && typeof parsed === "object") {
256
355
  const frontmatter = parsed;
257
356
  if (typeof frontmatter.name === "string" && frontmatter.name.trim()) {
@@ -281,7 +380,7 @@ ${body}`;
281
380
  };
282
381
 
283
382
  // src/utils/platforms/copilot.ts
284
- import yaml2 from "js-yaml";
383
+ import yaml3 from "js-yaml";
285
384
  var CopilotHandler = class {
286
385
  platform = "copilot";
287
386
  getTargetFileName(itemName, type) {
@@ -292,8 +391,8 @@ var CopilotHandler = class {
292
391
  }
293
392
  transform(content, type, itemName) {
294
393
  if (type !== "agent") return content;
295
- const frontmatterRegex2 = /^---\n([\s\S]*?)\n---/;
296
- const match = content.match(frontmatterRegex2);
394
+ const frontmatterRegex3 = /^---\n([\s\S]*?)\n---/;
395
+ const match = content.match(frontmatterRegex3);
297
396
  let frontmatter = {
298
397
  name: itemName,
299
398
  description: "",
@@ -303,7 +402,7 @@ var CopilotHandler = class {
303
402
  let body = content;
304
403
  if (match) {
305
404
  try {
306
- const parsed = yaml2.load(match[1]);
405
+ const parsed = yaml3.load(match[1]);
307
406
  frontmatter = { ...frontmatter, ...parsed };
308
407
  frontmatter.target = "github-copilot";
309
408
  frontmatter.tools = [
@@ -313,11 +412,11 @@ var CopilotHandler = class {
313
412
  "grep_search",
314
413
  "githubRepo"
315
414
  ];
316
- body = content.replace(frontmatterRegex2, "").trim();
415
+ body = content.replace(frontmatterRegex3, "").trim();
317
416
  } catch (_) {
318
417
  }
319
418
  }
320
- const yamlStr = yaml2.dump(frontmatter);
419
+ const yamlStr = yaml3.dump(frontmatter);
321
420
  return `---
322
421
  ${yamlStr}---
323
422
 
@@ -339,7 +438,7 @@ var DefaultHandler = class {
339
438
  };
340
439
 
341
440
  // src/utils/platforms/gemini.ts
342
- import yaml3 from "js-yaml";
441
+ import yaml4 from "js-yaml";
343
442
 
344
443
  // src/utils/toml.ts
345
444
  function convertToGeminiCommandTOML(markdownContent) {
@@ -382,8 +481,8 @@ var GeminiHandler = class {
382
481
  return convertToGeminiCommandTOML(content);
383
482
  }
384
483
  if (type === "agent") {
385
- const frontmatterRegex2 = /^---\n([\s\S]*?)\n---/;
386
- const match = content.match(frontmatterRegex2);
484
+ const frontmatterRegex3 = /^---\n([\s\S]*?)\n---/;
485
+ const match = content.match(frontmatterRegex3);
387
486
  let frontmatter = {
388
487
  name: itemName,
389
488
  description: "",
@@ -405,7 +504,7 @@ var GeminiHandler = class {
405
504
  let body = content;
406
505
  if (match) {
407
506
  try {
408
- const parsed = yaml3.load(match[1]);
507
+ const parsed = yaml4.load(match[1]);
409
508
  frontmatter = { ...frontmatter, ...parsed };
410
509
  frontmatter.tools = [
411
510
  "list_directory",
@@ -422,11 +521,11 @@ var GeminiHandler = class {
422
521
  "activate_skill"
423
522
  ];
424
523
  delete frontmatter.skills;
425
- body = content.replace(frontmatterRegex2, "").trim();
524
+ body = content.replace(frontmatterRegex3, "").trim();
426
525
  } catch (_) {
427
526
  }
428
527
  }
429
- const yamlStr = yaml3.dump(frontmatter);
528
+ const yamlStr = yaml4.dump(frontmatter);
430
529
  return `---
431
530
  ${yamlStr}---
432
531
 
@@ -437,12 +536,12 @@ ${body}`;
437
536
  };
438
537
 
439
538
  // src/utils/platforms/windsurf.ts
440
- import path4 from "node:path";
539
+ import path5 from "node:path";
441
540
  var WindsurfHandler = class {
442
541
  platform = "windsurf";
443
542
  getTargetFileName(itemName, type) {
444
543
  if (type === "agent") {
445
- return path4.join(path4.parse(itemName).name, "AGENTS.md");
544
+ return path5.join(path5.parse(itemName).name, "AGENTS.md");
446
545
  }
447
546
  return itemName;
448
547
  }
@@ -457,6 +556,7 @@ function registerHandler(handler) {
457
556
  handlers.set(handler.platform, handler);
458
557
  }
459
558
  registerHandler(new AntigravityHandler());
559
+ registerHandler(new ClaudeCodeHandler());
460
560
  registerHandler(new CodexHandler());
461
561
  registerHandler(new CopilotHandler());
462
562
  registerHandler(new GeminiHandler());
@@ -475,7 +575,7 @@ function getPlatformOptions(type) {
475
575
  }));
476
576
  }
477
577
  async function installItem(itemName, overwrite, sourcePath, targetBaseDir) {
478
- const targetPath = path5.join(targetBaseDir, itemName);
578
+ const targetPath = path6.join(targetBaseDir, itemName);
479
579
  if (!await fs4.pathExists(sourcePath)) {
480
580
  throw new Error(`Item '${itemName}' not found at ${sourcePath}`);
481
581
  }
@@ -584,7 +684,7 @@ async function add(type, url, options) {
584
684
  const handler = getHandler(platform);
585
685
  for (const item of selectedItems) {
586
686
  const targetItemName = handler.getTargetFileName(item, normalizedType);
587
- const targetPath = path5.join(targetBase, targetItemName);
687
+ const targetPath = path6.join(targetBase, targetItemName);
588
688
  if (await fs4.pathExists(targetPath)) {
589
689
  existingItems.push({ item, platform });
590
690
  }
@@ -627,14 +727,14 @@ async function add(type, url, options) {
627
727
  try {
628
728
  let currentSourcePath;
629
729
  if (url && tempDir) {
630
- const potentialFile = path5.join(tempDir, item);
730
+ const potentialFile = path6.join(tempDir, item);
631
731
  if (await fs4.pathExists(potentialFile) && (await fs4.stat(potentialFile)).isFile()) {
632
732
  currentSourcePath = potentialFile;
633
733
  } else {
634
734
  currentSourcePath = tempDir;
635
735
  }
636
736
  } else {
637
- const src = path5.join(TYPE_DIRS[normalizedType], item);
737
+ const src = path6.join(TYPE_DIRS[normalizedType], item);
638
738
  if ((await fs4.stat(src)).isFile()) {
639
739
  currentSourcePath = src;
640
740
  } else {
@@ -647,7 +747,7 @@ async function add(type, url, options) {
647
747
  normalizedType
648
748
  );
649
749
  if ((normalizedType === "agent" || normalizedType === "workflow") && currentSourcePath.endsWith(".md")) {
650
- const targetPath = path5.join(targetBase, targetItemName);
750
+ const targetPath = path6.join(targetBase, targetItemName);
651
751
  if (!overwrite && await fs4.pathExists(targetPath)) {
652
752
  skippedCount++;
653
753
  } else {
@@ -655,9 +755,9 @@ async function add(type, url, options) {
655
755
  content = handler.transform(
656
756
  content,
657
757
  normalizedType,
658
- path5.parse(item).name
758
+ path6.parse(item).name
659
759
  );
660
- await fs4.ensureDir(path5.dirname(targetPath));
760
+ await fs4.ensureDir(path6.dirname(targetPath));
661
761
  await fs4.writeFile(targetPath, content);
662
762
  installedCount++;
663
763
  }
@@ -715,7 +815,7 @@ async function add(type, url, options) {
715
815
  }
716
816
 
717
817
  // src/commands/import.ts
718
- import path6 from "node:path";
818
+ import path7 from "node:path";
719
819
  import {
720
820
  cancel as cancel2,
721
821
  confirm as confirm2,
@@ -784,12 +884,12 @@ async function importItem(type, url, options) {
784
884
  throw e;
785
885
  }
786
886
  const shouldFlatten = (normalizedType === "agent" || normalizedType === "workflow") && !isFile;
787
- const targetPath = shouldFlatten ? targetBaseDir : path6.join(targetBaseDir, itemName);
887
+ const targetPath = shouldFlatten ? targetBaseDir : path7.join(targetBaseDir, itemName);
788
888
  if (shouldFlatten) {
789
889
  const srcFiles = await fs5.readdir(tempDir);
790
890
  const conflicts = [];
791
891
  for (const file of srcFiles) {
792
- if (await fs5.pathExists(path6.join(targetBaseDir, file))) {
892
+ if (await fs5.pathExists(path7.join(targetBaseDir, file))) {
793
893
  conflicts.push(file);
794
894
  }
795
895
  }
@@ -820,7 +920,7 @@ async function importItem(type, url, options) {
820
920
  s.start(`Importing ${itemName} to ${targetBaseDir}...`);
821
921
  await fs5.ensureDir(targetBaseDir);
822
922
  if (isFile) {
823
- await fs5.copy(path6.join(tempDir, itemName), targetPath, {
923
+ await fs5.copy(path7.join(tempDir, itemName), targetPath, {
824
924
  overwrite: true
825
925
  });
826
926
  } else {
@@ -965,7 +1065,7 @@ async function list(type, options) {
965
1065
  }
966
1066
 
967
1067
  // src/commands/remove.ts
968
- import path7 from "node:path";
1068
+ import path8 from "node:path";
969
1069
  import {
970
1070
  confirm as confirm3,
971
1071
  intro as intro4,
@@ -1079,7 +1179,7 @@ async function remove(type, options) {
1079
1179
  const targetBase = targetPaths[platform];
1080
1180
  if (!targetBase) continue;
1081
1181
  for (const item of selectedItems) {
1082
- const targetPath = path7.join(targetBase, item);
1182
+ const targetPath = path8.join(targetBase, item);
1083
1183
  if (await fs7.pathExists(targetPath)) {
1084
1184
  sDel.message(`Removing ${pc4.bold(item)} from ${pc4.cyan(platform)}...`);
1085
1185
  try {
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: git-convention
3
+ description: This skill should be used when the user asks to "create a branch", "commit changes", "create a pull request", "manage branches", or "follow conventional commits". Provides guidelines for version control workflows and commit message formatting.
4
+ version: 1.0.0
5
+ ---
6
+
7
+ # Git Convention
8
+
9
+ Guide for managing version control workflows, including branching strategies, commit message formatting following Conventional Commits, and pull request management.
10
+
11
+ ## When to Use This Skill
12
+
13
+ - Creating new feature, bugfix, or maintenance branches
14
+ - Formatting commit messages to follow project standards
15
+ - Preparing and creating pull requests
16
+ - Managing branch lifecycle and cleanup
17
+ - Ensuring consistency across the repository's history
18
+
19
+ ## Branching Strategy
20
+
21
+ Follow a consistent naming convention for branches to ensure clarity and organization.
22
+
23
+ ### Branch Naming Convention
24
+
25
+ Use a prefix followed by a descriptive name in kebab-case:
26
+
27
+ - `feature/` - New features or significant functional additions (e.g., `feature/user-authentication`)
28
+ - `fix/` - Bug fixes and patches (e.g., `fix/login-error`)
29
+ - `refactor/` - Code restructuring without changing behavior (e.g., `refactor/api-client`)
30
+ - `docs/` - Documentation updates (e.g., `docs/update-readme`)
31
+ - `chore/` - Maintenance tasks, dependency updates, or internal tooling (e.g., `chore/update-deps`)
32
+ - `test/` - Adding or modifying tests (e.g., `test/unit-tests-auth`)
33
+
34
+ ### Workflow
35
+
36
+ 1. Start from the main integration branch (e.g., `main` or `develop`).
37
+ 2. Ensure the local branch is up-to-date: `git pull origin main`.
38
+ 3. Create the new branch: `git checkout -b <prefix>/<description>`.
39
+
40
+ ## Conventional Commits
41
+
42
+ Format commit messages according to the [Conventional Commits](https://www.conventionalcommits.org/) specification to enable automated changelog generation and easier history browsing.
43
+
44
+ ### Structure
45
+
46
+ ```
47
+ <type>(<scope>): <description>
48
+
49
+ [optional body]
50
+
51
+ [optional footer(s)]
52
+ ```
53
+
54
+ ### Types
55
+
56
+ - `feat`: A new feature
57
+ - `fix`: A bug fix
58
+ - `docs`: Documentation only changes
59
+ - `style`: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)
60
+ - `refactor`: A code change that neither fixes a bug nor adds a feature
61
+ - `perf`: A code change that improves performance
62
+ - `test`: Adding missing tests or correcting existing tests
63
+ - `build`: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
64
+ - `ci`: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
65
+ - `chore`: Other changes that don't modify src or test files
66
+ - `revert`: Reverts a previous commit
67
+
68
+ ### Guidelines
69
+
70
+ - **Description**: Use the imperative, present tense (e.g., "add", not "added" or "adds").
71
+ - **Case**: The description should be in lower-case or sentence-case.
72
+ - **Scope**: Use a scope to provide additional contextual information (e.g., `feat(auth): add login validation`).
73
+ - **Body**: Use the body to explain the "what" and "why" of the change, not the "how".
74
+ - **Footer**: Use the footer to reference issues (e.g., `Closes #123`) or breaking changes.
75
+
76
+ ## Pull Request Management
77
+
78
+ Create clear and informative pull requests to facilitate effective code review and collaboration.
79
+
80
+ ### PR Creation Process
81
+
82
+ 1. **Push your branch**: `git push origin <branch-name>`.
83
+ 2. **Open the PR**: Use the GitHub CLI or web interface.
84
+ 3. **Title**: Use the Conventional Commits format for the title (e.g., `feat(ui): add dashboard widgets`).
85
+ 4. **Description**: Use a template (if available) to describe:
86
+ - What changes were made.
87
+ - Why they were made.
88
+ - How they were tested.
89
+ - Any breaking changes or new dependencies.
90
+
91
+ ### Best Practices
92
+
93
+ - **Keep it focused**: One PR per logical change. Avoid "mega-PRs".
94
+ - **Self-review**: Review your own changes before asking others.
95
+ - **Link issues**: Use keywords like `Fixes #123` or `Closes #123` in the description.
96
+ - **Update regularly**: Rebase or merge from the main branch if the PR becomes stale.
97
+
98
+ ## Additional Resources
99
+
100
+ ### Reference Files
101
+
102
+ For detailed patterns and advanced git workflows, consult:
103
+
104
+ - **`references/conventional-commits.md`** - Detailed Conventional Commits specification.
105
+ - **`references/branching-workflows.md`** - Advanced branching and merging strategies.
106
+
107
+ ### Example Files
108
+
109
+ Working examples in `examples/`:
110
+
111
+ - **`commit-messages.txt`** - Examples of well-formatted commit messages.
112
+ - **`pr-description-template.md`** - A standard PR description template.
@@ -0,0 +1,34 @@
1
+ # Example Commit Messages
2
+
3
+ ## Features
4
+ - `feat(ui): add progress bar component`
5
+ - `feat(auth): implement oauth2 login with google`
6
+ - `feat!: change default api version to v2`
7
+
8
+ ## Bug Fixes
9
+ - `fix(parser): handle empty input string gracefully`
10
+ - `fix: resolve race condition in database connection pool`
11
+ - `fix(styles): fix padding issues on mobile devices`
12
+
13
+ ## Documentation
14
+ - `docs: update readme with installation instructions`
15
+ - `docs(api): document the new /user/profile endpoint`
16
+ - `docs: add contributing guide`
17
+
18
+ ## Refactoring
19
+ - `refactor(core): simplify the request handling logic`
20
+ - `refactor: move utility functions to a separate module`
21
+ - `refactor(tests): reduce duplication in integration tests`
22
+
23
+ ## Performance
24
+ - `perf(image): optimize image loading speed using lazy-loading`
25
+ - `perf: add caching layer for frequently accessed data`
26
+
27
+ ## Tests
28
+ - `test(auth): add unit tests for jwt validation`
29
+ - `test: increase coverage for the math module`
30
+
31
+ ## Chore
32
+ - `chore: update dependencies`
33
+ - `chore(deps): bump vite from 4.0 to 5.0`
34
+ - `chore: remove unused log statements`
@@ -0,0 +1,40 @@
1
+ ## Summary
2
+ <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
3
+
4
+ ## Related Issue
5
+ <!-- Link to the issue this PR addresses (e.g., Fixes #123, Closes #456) -->
6
+ Fixes #
7
+
8
+ ## Type of Change
9
+ <!-- Please delete options that are not relevant -->
10
+ - [ ] Bug fix (non-breaking change which fixes an issue)
11
+ - [ ] New feature (non-breaking change which adds functionality)
12
+ - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
13
+ - [ ] Documentation update
14
+ - [ ] Refactor (code change that neither fixes a bug nor adds a feature)
15
+
16
+ ## How did you test this change?
17
+ <!--
18
+ Please describe the tests that you ran to verify your changes.
19
+ Provide instructions so we can reproduce.
20
+ Please also list any relevant details for your test configuration.
21
+ -->
22
+ - [ ] Test Case A: ...
23
+ - [ ] Test Case B: ...
24
+
25
+ ### Screenshots (if applicable)
26
+ <!-- Add images to show visual changes -->
27
+
28
+ ## Checklist
29
+
30
+ - [ ] I have read the [CONTRIBUTING](CONTRIBUTING.md) document.
31
+ - [ ] My code follows the code style of this project.
32
+ - [ ] I have performed a self-review of my own code.
33
+ - [ ] I have commented my code, particularly in hard-to-understand areas.
34
+ - [ ] I have made corresponding changes to the documentation.
35
+ - [ ] My changes generate no new warnings.
36
+ - [ ] I have added tests that prove my fix is effective or that my feature works.
37
+ - [ ] New and existing unit tests pass locally with my changes.
38
+
39
+ ## Special notes for your reviewer
40
+ <!-- Any specific areas you want the reviewer to focus on? -->
@@ -0,0 +1,63 @@
1
+ # Advanced Branching and Merging Strategies
2
+
3
+ Choosing the right branching strategy is crucial for team collaboration and continuous delivery.
4
+
5
+ ## Gitflow Workflow
6
+
7
+ Gitflow is a legacy Git workflow that was first published and made popular by Vincent Driessen. It's often used for projects that have a scheduled release cycle.
8
+
9
+ - `main` branch stores the official release history.
10
+ - `develop` branch serves as an integration branch for features.
11
+ - `feature/*` branches are used for developing new features.
12
+ - `release/*` branches support preparation of a new production release.
13
+ - `hotfix/*` branches are used to quickly patch production releases.
14
+
15
+ ## GitHub Flow
16
+
17
+ GitHub Flow is a lightweight, branch-based workflow that supports teams and projects where deployments happen regularly.
18
+
19
+ - Anything in the `main` branch is deployable.
20
+ - To work on something new, create a descriptive branch off of `main`.
21
+ - Commit to that branch locally and regularly push your work to the same named branch on the server.
22
+ - When you need feedback or help, or you think the branch is ready for merging, open a pull request.
23
+ - After someone else has reviewed and signed off on the feature, you can merge it into `main`.
24
+ - Once it is merged and pushed to `main`, you can and should deploy immediately.
25
+
26
+ ## Trunk-Based Development
27
+
28
+ A version control management strategy where developers merge small, frequent updates to a core “trunk” or main branch.
29
+
30
+ - High frequency of commits.
31
+ - Small PRs.
32
+ - Continuous Integration.
33
+ - Feature flags are often used to hide work-in-progress.
34
+
35
+ ## Merging vs Rebasing
36
+
37
+ ### Merging
38
+
39
+ `git merge` is a "non-destructive" operation. The existing branches are not changed in any way. This avoids all of the potential pitfalls of rebasing.
40
+
41
+ ```bash
42
+ git checkout feature/abc
43
+ git merge main
44
+ ```
45
+
46
+ ### Rebasing
47
+
48
+ `git rebase` moves the entire feature branch to begin on the tip of the `main` branch, effectively incorporating all of the new commits in `main`. It re-writes the project history by creating brand new commits for each commit in the original branch.
49
+
50
+ ```bash
51
+ git checkout feature/abc
52
+ git rebase main
53
+ ```
54
+
55
+ **Golden Rule of Rebasing**: Never use it on public branches.
56
+
57
+ ## Conflict Resolution
58
+
59
+ 1. Identify the conflict: `git status` will show unmerged paths.
60
+ 2. Open the files and look for `<<<<<<<`, `=======`, `>>>>>>>`.
61
+ 3. Decide which changes to keep.
62
+ 4. Stage the resolved files: `git add <file>`.
63
+ 5. Complete the merge or rebase: `git commit` or `git rebase --continue`.
@@ -0,0 +1,85 @@
1
+ # Conventional Commits Specification
2
+
3
+ The Conventional Commits specification is a lightweight convention on top of commit messages. It provides an easy set of rules for creating an explicit commit history; which makes it easier to write automated tools on top of.
4
+
5
+ ## The Specification
6
+
7
+ The commit message should be structured as follows:
8
+
9
+ ```
10
+ <type>[optional scope]: <description>
11
+
12
+ [optional body]
13
+
14
+ [optional footer(s)]
15
+ ```
16
+
17
+ ### Type
18
+
19
+ The type is a short string that describes the category of the change. Common types include:
20
+
21
+ - `feat`: (feature)
22
+ - `fix`: (bug fix)
23
+ - `docs`: (documentation)
24
+ - `style`: (formatting, missing semi-colons, etc; no code change)
25
+ - `refactor`: (refactoring production code)
26
+ - `test`: (adding missing tests, refactoring tests; no production code change)
27
+ - `chore`: (updating grunt tasks etc; no production code change)
28
+
29
+ ### Scope
30
+
31
+ A scope MAY be provided after a type. A scope MUST consist of a noun describing a section of the codebase surrounded by parenthesis, e.g., `fix(parser):`
32
+
33
+ ### Description
34
+
35
+ The description contains a succinct description of the change:
36
+
37
+ - use the imperative, present tense: "change" not "changed" nor "changes"
38
+ - don't capitalize the first letter
39
+ - no dot (.) at the end
40
+
41
+ ### Body
42
+
43
+ A longer commit body MAY be provided after the short description, providing additional contextual information about the code changes. The body MUST begin one blank line after the description.
44
+
45
+ ### Footer
46
+
47
+ One or more footers MAY be provided one blank line after the body. Each footer MUST consist of a word token, followed by either a `:<space>` or `<space>#` separator, followed by a string value (this is inspired by the git trailer convention).
48
+
49
+ ### Breaking Changes
50
+
51
+ A breaking change MUST be indicated by an `!` after the type/scope, or as a footer entry starting with `BREAKING CHANGE:`.
52
+
53
+ ## Examples
54
+
55
+ ### Commit message with description and breaking change footer
56
+
57
+ ```
58
+ feat: allow provided config object to extend other configs
59
+
60
+ BREAKING CHANGE: `extends` key in config file is now used for extending other config files
61
+ ```
62
+
63
+ ### Commit message with ! to draw attention to breaking change
64
+
65
+ ```
66
+ feat!: send an email to the customer when a product is shipped
67
+ ```
68
+
69
+ ### Commit message with scope and ! to draw attention to breaking change
70
+
71
+ ```
72
+ chore(api)!: drop support for Node 6
73
+ ```
74
+
75
+ ### Commit message with multi-paragraph body and multiple footers
76
+
77
+ ```
78
+ fix: prevent racing of requests
79
+
80
+ Introduce a request id and a reference to latest request. All
81
+ rest responses are checked against the current id before update.
82
+
83
+ Reviewers: adrian, jdoe
84
+ Fixes #123
85
+ ```
@@ -0,0 +1,66 @@
1
+ # Pull Request Description Best Practices
2
+
3
+ A well-crafted pull request (PR) description is essential for effective code review, maintaining project history, and ensuring that changes meet quality standards.
4
+
5
+ ## Core Components
6
+
7
+ The most effective PR templates across major open-source repositories (like React, VS Code, and Kubernetes) share these core components:
8
+
9
+ ### 1. Summary & Motivation
10
+
11
+ Explain **what** you changed and **why** you changed it.
12
+
13
+ - What problem does this PR solve?
14
+ - What is the context for this change?
15
+ - Are there any architectural decisions or trade-offs made?
16
+
17
+ ### 2. Related Issues
18
+
19
+ Always link to the issue(s) being addressed. Use keywords that GitHub recognizes to automatically close issues when the PR is merged:
20
+
21
+ - `Fixes #123`
22
+
23
+ - `Closes #123`
24
+
25
+ - `Resolves #123`
26
+
27
+ ### 3. Type of Change
28
+
29
+ Categorize the PR to help maintainers quickly understand its impact:
30
+
31
+ - **Bug Fix**: Non-breaking change that fixes an issue.
32
+
33
+ - **New Feature**: Non-breaking change that adds functionality.
34
+
35
+ - **Breaking Change**: Fix or feature that would cause existing functionality to change.
36
+ - **Documentation**: Changes to documentation only.
37
+ - **Refactor**: Code change that neither fixes a bug nor adds a feature.
38
+
39
+ ### 4. Test Plan (Verification)
40
+
41
+ Describe how you verified your changes. This is the most critical section for reviewers.
42
+
43
+ - **Automated Tests**: Mention new or existing tests that cover the changes.
44
+ - **Manual Testing**: List the steps taken to manually verify the behavior.
45
+ - **Screenshots/Gifs**: Provide visual evidence for UI/UX changes.
46
+
47
+ ### 5. Checklist
48
+
49
+ A set of mandatory steps the contributor must confirm:
50
+
51
+ - [ ] My code follows the project's style guidelines.
52
+ - [ ] I have performed a self-review of my code.
53
+ - [ ] I have added tests that cover my changes.
54
+ - [ ] All new and existing tests passed.
55
+ - [ ] I have updated the documentation accordingly.
56
+
57
+ ### 6. Special Notes for Reviewers
58
+
59
+ Use this section to highlight specific areas where you need feedback or to explain complex logic that might be hard to follow.
60
+
61
+ ## Best Practices
62
+
63
+ - **Keep it focused**: One logical change per PR. Small PRs are easier to review and less likely to introduce bugs.
64
+ - **Write for the future**: Your PR description will be part of the repository's history. Write it so that someone reading it a year from now can understand the context.
65
+ - **Be concise but thorough**: Avoid "fluff," but don't leave out critical information.
66
+ - **Update the description**: If the PR evolves during the review process, update the description to reflect the final state of the changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurokeita/add-skill",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "CLI to install AI agent skills to various platforms",
5
5
  "type": "module",
6
6
  "bin": {