Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Skill Md Laravel Package

stolt/skill-md

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require stolt/skill-md
    

    Ensure your composer.json has "php": "^8.2" in require section.

  2. First Use Case: Define a skill in your Laravel app (e.g., for a service or API endpoint):

    use Stolt\SkillMd\SkillMd;
    
    $skill = SkillMd::fromArray([
        'name' => 'User Authentication',
        'description' => 'Handles JWT-based authentication.',
        'body' => '# Features
        - Login/Logout
        - Token refresh
        - Role-based access',
        'version' => '1.0.0',
        'tags' => ['auth', 'security'],
    ]);
    
  3. Where to Look First:

    • SkillMd class: Core abstraction for SKILL.md files.
    • toMarkdown(): Convert skill data to Markdown for documentation.
    • fromArray()/create(): Initialize from structured data.

Implementation Patterns

Core Workflows

  1. Skill Documentation Generation:

    // In a Laravel controller or service
    public function generateSkillDocs()
    {
        $skill = SkillMd::fromArray([...]);
        $markdown = $skill->toMarkdown();
    
        // Save to file or render in a view
        Storage::put('skills/auth.md', $markdown);
        return response()->view('skills.show', ['markdown' => $markdown]);
    }
    
  2. Dynamic Skill Metadata: Use in Laravel Service Providers or API Resources to attach metadata:

    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        $skills = collect([
            ['name' => 'Email Service', 'tags' => ['mail', 'queue']],
            ['name' => 'Payment Gateway', 'tags' => ['payments']],
        ])->map(fn($data) => SkillMd::fromArray($data));
    
        view()->share('skills', $skills);
    }
    
  3. Validation Integration: Combine with Laravel’s Form Requests for skill validation:

    use Stolt\SkillMd\SkillMd;
    
    public function rules()
    {
        return [
            'skill.name' => 'required|string|max:255',
            'skill.description' => 'required|string',
            'skill.tags' => 'array',
            'skill.tags.*' => 'string',
        ];
    }
    
    protected function prepareForValidation()
    {
        $this->merge([
            'skill' => SkillMd::fromArray($this->all())->toArray(),
        ]);
    }
    
  4. Markdown Rendering: Use with Laravel Markdown packages (e.g., spatie/laravel-markdown) to render skills in Blade:

    @markdown($skill->toMarkdown())
    

Integration Tips

  • Laravel Scout: Attach skills to models for searchable documentation:

    class ApiEndpoint extends Model
    {
        public function skill()
        {
            return $this->morphOne(Skill::class, 'skillable');
        }
    }
    
    $endpoint->skill = SkillMd::fromArray([...])->toMarkdown();
    $endpoint->save();
    
  • API Metadata: Return skill data in API responses:

    return response()->json([
        'data' => $resource,
        'metadata' => [
            'skill' => SkillMd::fromArray($skillData)->toArray(),
        ],
    ]);
    
  • Caching: Cache generated Markdown for performance:

    $markdown = Cache::remember("skill:{$skill->name()}", now()->addHours(1), function() use ($skill) {
        return $skill->toMarkdown();
    });
    

Gotchas and Tips

Pitfalls

  1. Field Whitelisting: The package filters unsupported fields (e.g., unsupported-field returns null). Always check has() before accessing:

    if ($skill->has('custom-field')) {
        $value = $skill->get('custom-field');
    }
    
  2. Markdown Parsing:

    • body is treated as raw Markdown. Escape dynamic content to avoid XSS:
      $safeBody = e($skill->body());
      
    • Use htmlspecialchars() if rendering user-provided Markdown.
  3. Case Sensitivity:

    • Frontmatter keys in generated Markdown are lowercased (e.g., namename:). Ensure consistency when parsing back.
  4. Versioning: The package lacks semver validation. Validate version manually:

    use Symfony\Component\Validator\Constraints as Assert;
    
    $validator = Validator::make(['version' => $skill->version()], [
        'version' => [new Assert\Regex('/^\d+\.\d+\.\d+$/')],
    ]);
    

Debugging

  • Inspect Raw Data:
    dd($skill->toArray()); // Debug unsupported fields
    
  • Markdown Output: Log generated Markdown to verify formatting:
    Log::debug('Skill Markdown:', ['markdown' => $skill->toMarkdown()]);
    

Extension Points

  1. Custom Fields: Extend the class to support additional fields:

    class ExtendedSkillMd extends SkillMd
    {
        protected $customFields = ['author', 'maintainer'];
    
        public function author()
        {
            return $this->get('author');
        }
    }
    
  2. Markdown Templates: Override toMarkdown() to customize frontmatter or body:

    $skill->toMarkdown(function ($markdown) {
        return str_replace('---', '---\ncustom-field: value', $markdown);
    });
    
  3. Laravel Service Container: Bind the package to a custom interface for dependency injection:

    $this->app->bind(SkillInterface::class, function () {
        return new SkillMd(...);
    });
    

Laravel-Specific Tips

  • Configuration: Store default skill metadata in config/skill.php:

    return [
        'default' => [
            'license' => 'MIT',
            'version' => '1.0.0',
        ],
    ];
    

    Merge defaults in SkillMd constructor:

    $skill = new SkillMd(
        'Name',
        'Description',
        'Body',
        array_merge(config('skill.default'), $customMetadata)
    );
    
  • Artisan Commands: Generate skills from database records:

    class GenerateSkillsCommand extends Command
    {
        public function handle()
        {
            $skills = Model::all()->map(fn($model) => SkillMd::fromArray([
                'name' => $model->name,
                'body' => $model->description,
                'tags' => $model->tags,
            ]));
    
            foreach ($skills as $skill) {
                Storage::put("skills/{$skill->name()}.md", $skill->toMarkdown());
            }
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky