Skip to content

Commit 54b0c6d

Browse files
macclaude
authored andcommitted
feat: add create-skill — AI-powered skill generator
dex create-skill <name> -d "description" [--install] Aliases: dex new-skill Uses agentic tool loop to generate manifest.json + handler.ts from natural language description. Optionally auto-installs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 753bff8 commit 54b0c6d

2 files changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import type { SkillHandler } from "../../types.js";
2+
import { streamQuery } from "../../handler-utils.js";
3+
4+
const SYSTEM_PROMPT = `You are an expert at creating dex CLI skills. Your job is to generate a complete, working skill based on the user's description.
5+
6+
A dex skill consists of two files in a directory:
7+
8+
## 1. manifest.json
9+
10+
\`\`\`json
11+
{
12+
"name": "skill-name",
13+
"version": "1.0.0",
14+
"description": "What this skill does",
15+
"inputs": {
16+
"args": [
17+
{ "name": "file", "description": "Target file", "required": true }
18+
],
19+
"flags": [
20+
{ "name": "verbose", "short": "v", "type": "boolean", "default": false }
21+
],
22+
"context": ["current-file", "git-diff", "git-diff-staged", "git-log", "file-tree", "package-json", "stdin"]
23+
},
24+
"agent": {
25+
"maxTurns": 5,
26+
"allowedTools": ["bash", "read_file", "write_file", "list_files", "search_files", "apply_diff"]
27+
},
28+
"aliases": ["short-name"]
29+
}
30+
\`\`\`
31+
32+
Rules:
33+
- "name" must be lowercase with hyphens
34+
- Only include "args", "flags", "context" that the skill actually needs
35+
- Only include "agent.allowedTools" if the skill needs to read/write files or run commands
36+
- Omit "agent" entirely for simple single-turn skills (review, explain, etc.)
37+
38+
## 2. handler.ts
39+
40+
\`\`\`typescript
41+
import type { SkillHandler } from "../../types.js";
42+
import { streamQuery } from "../../handler-utils.js";
43+
44+
const SYSTEM_PROMPT = \\\`Your system prompt here\\\`;
45+
46+
const handler: SkillHandler = async (ctx) => {
47+
// Access inputs:
48+
// ctx.args.file — positional arg
49+
// ctx.flags.verbose — flag value
50+
// ctx.context.gitDiff — context data
51+
// ctx.context.currentFile?.content — file content
52+
// ctx.context.stdin — piped input
53+
// ctx.context.cwd — working directory
54+
55+
const prompt = \\\`Your prompt with \${ctx.context.currentFile?.content}\\\`;
56+
await streamQuery(ctx.agent, prompt, { systemPrompt: SYSTEM_PROMPT });
57+
};
58+
59+
export default handler;
60+
\`\`\`
61+
62+
## Your workflow:
63+
64+
1. Understand what the user wants
65+
2. Design the manifest (what inputs, context, and tools are needed)
66+
3. Write the handler with a good system prompt
67+
4. Create the skill directory with write_file
68+
5. If the user wants it installed, run: \`dex skill add ./<name>\`
69+
70+
Keep skills simple and focused. One skill = one job.`;
71+
72+
const handler: SkillHandler = async (ctx) => {
73+
const name = ctx.args.name;
74+
const description = ctx.flags.description as string | undefined;
75+
const install = ctx.flags.install as boolean;
76+
77+
if (!name) {
78+
throw new Error("Skill name is required. Usage: dex create-skill <name> -d 'what it does'");
79+
}
80+
81+
const prompt = `Create a new dex skill called "${name}" in the directory "./${name}/".
82+
83+
${description ? `Description: ${description}` : "Ask me what this skill should do, then create it."}
84+
85+
${install ? "After creating the files, install it by running: dex skill add ./" + name : ""}
86+
87+
${ctx.context.fileTree ? `Current project structure for reference:\n\`\`\`\n${ctx.context.fileTree}\n\`\`\`` : ""}
88+
89+
Create the manifest.json and handler.ts files now.`;
90+
91+
await streamQuery(ctx.agent, prompt, { systemPrompt: SYSTEM_PROMPT });
92+
};
93+
94+
export default handler;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "create-skill",
3+
"version": "1.0.0",
4+
"description": "Generate a new dex skill from a natural language description",
5+
"inputs": {
6+
"args": [
7+
{ "name": "name", "description": "Skill name (lowercase-with-hyphens)", "required": true }
8+
],
9+
"flags": [
10+
{
11+
"name": "description",
12+
"short": "d",
13+
"type": "string",
14+
"description": "What the skill should do"
15+
},
16+
{
17+
"name": "install",
18+
"type": "boolean",
19+
"description": "Automatically install after creation",
20+
"default": false
21+
}
22+
],
23+
"context": ["file-tree"]
24+
},
25+
"agent": {
26+
"maxTurns": 10,
27+
"allowedTools": ["read_file", "write_file", "list_files", "bash"]
28+
},
29+
"aliases": ["new-skill"]
30+
}

0 commit comments

Comments
 (0)