Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,31 @@ skillkit methodology load # Load a methodology
### Publishing & Sharing

```bash
skillkit publish # Publish skill to marketplace
skillkit publish # Generate well-known hosting structure
skillkit publish submit # Submit to SkillKit marketplace
skillkit create # Create new skill
skillkit init # Initialize in project
```

#### Self-Hosting Skills (RFC 8615)

Generate a well-known URI structure to host skills on your own domain:

```bash
# Generate hosting structure
skillkit publish ./my-skills --output ./public

# Users install from your domain
skillkit add https://your-domain.com
```

This creates:
```
.well-known/skills/
index.json # Skill manifest
my-skill/SKILL.md # Skill files
```

### Configuration

```bash
Expand Down
2 changes: 2 additions & 0 deletions apps/skillkit/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
AICommand,
AuditCommand,
PublishCommand,
PublishSubmitCommand,
AgentCommand,
AgentListCommand,
AgentShowCommand,
Expand Down Expand Up @@ -150,6 +151,7 @@ cli.register(CommandCmd);
cli.register(AICommand);
cli.register(AuditCommand);
cli.register(PublishCommand);
cli.register(PublishSubmitCommand);
cli.register(AgentCommand);
cli.register(AgentListCommand);
cli.register(AgentShowCommand);
Expand Down
10 changes: 9 additions & 1 deletion docs/fumadocs/content/docs/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,18 @@ skillkit init # Initialize project
skillkit create <name> # Create new skill
skillkit validate [path] # Validate skill format
skillkit read <skills> # Read skill content
skillkit publish # Publish to marketplace
skillkit settings --set key=value # Configure settings
```

## Publishing Commands

```bash
skillkit publish [path] # Generate well-known hosting structure
skillkit publish --output dir # Output to specific directory
skillkit publish --dry-run # Preview without writing
skillkit publish submit # Submit to SkillKit marketplace
```

## Interactive TUI

```bash
Expand Down
33 changes: 32 additions & 1 deletion docs/fumadocs/content/docs/marketplace.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,39 @@ skillkit install anthropics/skills --agent claude-code,cursor

## Publish Skills

### Self-Host on Your Domain (Recommended)

Generate a well-known URI structure (RFC 8615) to host skills on your own domain:

```bash
# Create and validate your skill
skillkit create my-skill
skillkit validate my-skill
skillkit publish

# Generate hosting structure
skillkit publish ./my-skill --output ./public
```

This creates:
```
.well-known/skills/
index.json # Skill manifest for auto-discovery
my-skill/
SKILL.md # Your skill content
```

Deploy the `.well-known` folder to your web server. Users can then install via:

```bash
skillkit add https://your-domain.com
```

### Submit to SkillKit Marketplace

To submit your skill for inclusion in the central marketplace:

```bash
skillkit publish submit
```

This opens a GitHub issue for review by maintainers.
20 changes: 18 additions & 2 deletions docs/fumadocs/content/docs/skills.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ Or manually create a `SKILL.md` file following the format above.
# Test locally
skillkit validate ./my-skill

# Publish to marketplace
skillkit publish
# Generate well-known hosting structure for self-hosting
skillkit publish ./my-skill --output ./public

# Or submit to SkillKit marketplace
skillkit publish submit
```

### Self-Hosting

The `skillkit publish` command generates an RFC 8615 well-known URI structure:

```
.well-known/skills/
index.json # Manifest for auto-discovery
my-skill/
SKILL.md # Skill content
```

Deploy to your domain and users can install via `skillkit add https://your-domain.com`.
23 changes: 7 additions & 16 deletions packages/cli/src/commands/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
isAgentInstalled,
type BundledAgent,
} from '@skillkit/resources';
// Agent discovery uses root directories, not skill directories

export class AgentCommand extends Command {
static override paths = [['agent']];
Expand Down Expand Up @@ -263,39 +262,33 @@ export class AgentCreateCommand extends Command {
});

async execute(): Promise<number> {
// Validate agent name format
const namePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/;
if (!namePattern.test(this.name)) {
console.log(chalk.red('Invalid agent name: must be lowercase alphanumeric with hyphens'));
console.log(chalk.dim('Examples: my-agent, code-reviewer, security-expert'));
return 1;
}

// Determine target directory
let targetDir: string;
if (this.global) {
targetDir = join(homedir(), '.claude', 'agents');
} else {
targetDir = join(process.cwd(), '.claude', 'agents');
}

// Create directory if needed
if (!existsSync(targetDir)) {
mkdirSync(targetDir, { recursive: true });
}

// Check if agent already exists
const agentPath = join(targetDir, `${this.name}.md`);
if (existsSync(agentPath)) {
console.log(chalk.red(`Agent already exists: ${agentPath}`));
return 1;
}

// Generate content
const description = this.description || `${this.name} agent`;
const content = generateAgentTemplate(this.name, description, this.model);

// Write file
writeFileSync(agentPath, content);

console.log(chalk.green(`Created agent: ${agentPath}`));
Expand Down Expand Up @@ -359,11 +352,9 @@ export class AgentTranslateCommand extends Command {
const searchDirs = [process.cwd()];
const targetAgent = this.to as AgentType;

// Get agents to translate
let agents: CustomAgent[];

if (this.source) {
// Translate from custom source path
const sourcePath = this.source.startsWith('/')
? this.source
: join(process.cwd(), this.source);
Expand Down Expand Up @@ -400,7 +391,6 @@ export class AgentTranslateCommand extends Command {
return 0;
}

// Determine output directory
const outputDir = this.output || getAgentTargetDirectory(process.cwd(), targetAgent);

console.log(chalk.cyan(`Translating ${agents.length} agent(s) to ${targetAgent} format...\n`));
Expand Down Expand Up @@ -433,7 +423,6 @@ export class AgentTranslateCommand extends Command {
}
}
} else {
// Create directory if needed
if (!existsSync(outputDir)) {
mkdirSync(outputDir, { recursive: true });
}
Expand Down Expand Up @@ -538,12 +527,10 @@ export class AgentValidateCommand extends Command {
let hasErrors = false;

if (this.agentPath) {
// Validate specific path
const result = validateAgent(this.agentPath);
printValidationResult(this.agentPath, result);
hasErrors = !result.valid;
} else if (this.all) {
// Validate all agents
const searchDirs = [process.cwd()];
const agents = findAllAgents(searchDirs);

Expand All @@ -568,8 +555,6 @@ export class AgentValidateCommand extends Command {
}
}

// Helper functions

function printAgent(agent: CustomAgent): void {
const status = agent.enabled ? chalk.green('✓') : chalk.red('○');
const name = agent.enabled ? agent.name : chalk.dim(agent.name);
Expand Down Expand Up @@ -949,7 +934,13 @@ export class AgentFromSkillCommand extends Command {
}
filename = `${sanitized}.md`;
} else {
filename = `${skill.name}.md`;
const sanitized = sanitizeFilename(skill.name);
if (!sanitized) {
console.log(chalk.red(`Invalid skill name for filename: ${skill.name}`));
console.log(chalk.dim('Skill name must contain only alphanumeric characters, hyphens, and underscores'));
return 1;
}
filename = `${sanitized}.md`;
}

const outputPath = join(targetDir, filename);
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export { PlanCommand } from './plan.js';
export { CommandCmd, CommandAvailableCommand, CommandInstallCommand } from './command.js';
export { AICommand } from './ai.js';
export { AuditCommand } from './audit.js';
export { PublishCommand } from './publish.js';
export { PublishCommand, PublishSubmitCommand } from './publish.js';
export {
AgentCommand,
AgentListCommand,
Expand Down
Loading