@waynesutton/convex-skills 1.0.6 → 1.0.8

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
@@ -35,6 +35,12 @@ convex-skills install convex-best-practices
35
35
  # Install all skills
36
36
  convex-skills install-all
37
37
 
38
+ # Install all skills to .agents/skills
39
+ convex-skills install-all --target agents
40
+
41
+ # Symlink SKILL.md files instead of copying
42
+ convex-skills install-all --target agents --link
43
+
38
44
  # Install templates (CLAUDE.md + skill templates)
39
45
  convex-skills install-templates
40
46
  ```
@@ -84,6 +90,15 @@ Codex will auto-discover `SKILL.md` files in that directory on the next start.
84
90
 
85
91
  If you are working from a repo clone, Codex also auto-discovers skills from `.codex/skills` at the repo root. You can symlink this repo’s `skills/*` into `.codex/skills` so updates flow through without copying.
86
92
 
93
+ ### Standard Agent Skills Path
94
+
95
+ Some tools are standardizing on `.agents/skills` for discovery. This repo supports that layout via the CLI:
96
+
97
+ ```bash
98
+ convex-skills install-all --target agents
99
+ convex-skills install-all --target agents --link
100
+ ```
101
+
87
102
  ### OpenCode
88
103
 
89
104
  OpenCode discovers skills from `~/.claude/skills/<name>/SKILL.md` automatically. See OpenCode Skills docs for more details.
@@ -142,6 +157,7 @@ convex-skills/
142
157
  │ └── ...
143
158
  ├── .codex/ # Codex integration (symlink skills here)
144
159
  │ └── README.md # Codex setup instructions
160
+ ├── .agents/ # Standard agent skills path
145
161
  ├── command/ # Slash command definitions (OpenCode)
146
162
  │ └── convex.md # /convex command entrypoint
147
163
  ├── templates/ # Templates for forking developers
package/bin/cli.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  existsSync,
10
10
  copyFileSync,
11
11
  readdirSync,
12
+ symlinkSync,
12
13
  } from "fs";
13
14
 
14
15
  const __filename = fileURLToPath(import.meta.url);
@@ -32,6 +33,12 @@ const SKILLS = {
32
33
  "convex-component-authoring": "Creating reusable Convex components",
33
34
  };
34
35
 
36
+ const TARGET_ALIASES = new Map([
37
+ ["claude", ".claude/skills"],
38
+ ["codex", ".codex/skills"],
39
+ ["agents", ".agents/skills"],
40
+ ]);
41
+
35
42
  function printHelp() {
36
43
  console.log(`
37
44
  convex-skills - Agent skills for building Convex applications
@@ -49,12 +56,17 @@ COMMANDS:
49
56
 
50
57
  OPTIONS:
51
58
  --dir <path> Target directory (default: current directory)
59
+ --target <name|path> Install target: claude, codex, agents, or a path
60
+ --link Symlink SKILL.md instead of copying
52
61
  --help, -h Show this help message
53
62
 
54
63
  EXAMPLES:
55
64
  convex-skills list
56
65
  convex-skills install convex-best-practices
57
66
  convex-skills install-all
67
+ convex-skills install-all --target agents
68
+ convex-skills install convex-functions --target .agents/skills
69
+ convex-skills install convex-best-practices --target codex --link
58
70
  convex-skills install-templates
59
71
  convex-skills show convex-functions
60
72
 
@@ -73,7 +85,27 @@ function listSkills() {
73
85
  console.log("");
74
86
  }
75
87
 
76
- function installSkill(skillName, targetDir) {
88
+ function ensureDir(dirPath) {
89
+ if (!existsSync(dirPath)) {
90
+ mkdirSync(dirPath, { recursive: true });
91
+ }
92
+ }
93
+
94
+ function resolveTargetSkillsDir(targetDir, target) {
95
+ if (!target) {
96
+ return join(targetDir, ".claude", "skills");
97
+ }
98
+
99
+ const alias = TARGET_ALIASES.get(target);
100
+ if (alias) {
101
+ return join(targetDir, alias);
102
+ }
103
+
104
+ const resolved = resolve(targetDir, target);
105
+ return resolved.endsWith("skills") ? resolved : join(resolved, "skills");
106
+ }
107
+
108
+ function installSkill(skillName, targetSkillsDir, useSymlink) {
77
109
  const skillsPath = join(packageRoot, "skills", skillName, "SKILL.md");
78
110
 
79
111
  if (!existsSync(skillsPath)) {
@@ -82,24 +114,24 @@ function installSkill(skillName, targetDir) {
82
114
  process.exit(1);
83
115
  }
84
116
 
85
- const targetPath = join(
86
- targetDir,
87
- ".claude",
88
- "skills",
89
- skillName,
90
- "SKILL.md",
91
- );
117
+ const targetPath = join(targetSkillsDir, skillName, "SKILL.md");
92
118
  const targetSkillDir = dirname(targetPath);
93
119
 
94
- if (!existsSync(targetSkillDir)) {
95
- mkdirSync(targetSkillDir, { recursive: true });
120
+ ensureDir(targetSkillDir);
121
+
122
+ if (useSymlink) {
123
+ if (!existsSync(targetPath)) {
124
+ symlinkSync(skillsPath, targetPath);
125
+ }
126
+ console.log(`Linked ${skillName} to ${targetPath}`);
127
+ return;
96
128
  }
97
129
 
98
130
  copyFileSync(skillsPath, targetPath);
99
131
  console.log(`Installed ${skillName} to ${targetPath}`);
100
132
  }
101
133
 
102
- function installAllSkills(targetDir) {
134
+ function installAllSkills(targetSkillsDir, useSymlink) {
103
135
  const skillsDir = join(packageRoot, "skills");
104
136
  const skills = readdirSync(skillsDir, { withFileTypes: true })
105
137
  .filter((dirent) => dirent.isDirectory())
@@ -108,11 +140,11 @@ function installAllSkills(targetDir) {
108
140
  console.log(`Installing ${skills.length} skills...\n`);
109
141
 
110
142
  skills.forEach((skillName) => {
111
- installSkill(skillName, targetDir);
143
+ installSkill(skillName, targetSkillsDir, useSymlink);
112
144
  });
113
145
 
114
146
  console.log(
115
- `\nDone! Installed ${skills.length} skills to ${join(targetDir, ".claude", "skills")}`,
147
+ `\nDone! Installed ${skills.length} skills to ${targetSkillsDir}`,
116
148
  );
117
149
  }
118
150
 
@@ -139,9 +171,7 @@ function installTemplates(targetDir) {
139
171
  );
140
172
  const targetSkillsDir = join(targetDir, ".claude", "skills");
141
173
 
142
- if (!existsSync(targetSkillsDir)) {
143
- mkdirSync(targetSkillsDir, { recursive: true });
144
- }
174
+ ensureDir(targetSkillsDir);
145
175
 
146
176
  templates.forEach((template) => {
147
177
  const src = join(skillTemplatesDir, template);
@@ -184,6 +214,8 @@ function printSkillPath(skillName) {
184
214
  // Parse arguments
185
215
  const args = process.argv.slice(2);
186
216
  let targetDir = process.cwd();
217
+ let target = null;
218
+ let useSymlink = false;
187
219
 
188
220
  // Check for --dir flag
189
221
  const dirIndex = args.indexOf("--dir");
@@ -192,8 +224,21 @@ if (dirIndex !== -1 && args[dirIndex + 1]) {
192
224
  args.splice(dirIndex, 2);
193
225
  }
194
226
 
227
+ const targetIndex = args.indexOf("--target");
228
+ if (targetIndex !== -1 && args[targetIndex + 1]) {
229
+ target = args[targetIndex + 1];
230
+ args.splice(targetIndex, 2);
231
+ }
232
+
233
+ const linkIndex = args.indexOf("--link");
234
+ if (linkIndex !== -1) {
235
+ useSymlink = true;
236
+ args.splice(linkIndex, 1);
237
+ }
238
+
195
239
  const command = args[0];
196
240
  const arg = args[1];
241
+ const targetSkillsDir = resolveTargetSkillsDir(targetDir, target);
197
242
 
198
243
  switch (command) {
199
244
  case "list":
@@ -205,10 +250,10 @@ switch (command) {
205
250
  console.log("Run 'convex-skills list' to see available skills.");
206
251
  process.exit(1);
207
252
  }
208
- installSkill(arg, targetDir);
253
+ installSkill(arg, targetSkillsDir, useSymlink);
209
254
  break;
210
255
  case "install-all":
211
- installAllSkills(targetDir);
256
+ installAllSkills(targetSkillsDir, useSymlink);
212
257
  break;
213
258
  case "install-templates":
214
259
  installTemplates(targetDir);
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@waynesutton/convex-skills",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Agent skills for building production-ready Convex applications. Includes best practices, functions, realtime patterns, schema validation, file storage, security audits, and more.",
5
- "author": "Wayne Sutton",
5
+ "author": "Wayne Sutton - @waynesutton",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
@@ -1,10 +1,6 @@
1
1
  ---
2
2
  name: convex-best-practices
3
- displayName: Convex Best Practices
4
3
  description: Guidelines for building production-ready Convex apps covering function organization, query patterns, validation, TypeScript usage, error handling, and the Zen of Convex design philosophy
5
- version: 1.0.0
6
- author: Convex
7
- tags: [convex, best-practices, typescript, production, error-handling]
8
4
  ---
9
5
 
10
6
  # Convex Best Practices