# Package Dev

> >

- **Type:** Skill
- **Install:** `agentstack add skill-nasrulhazim-agent-skills-package-dev`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [nasrulhazim](https://agentstack.voostack.com/s/nasrulhazim)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [nasrulhazim](https://github.com/nasrulhazim)
- **Source:** https://github.com/nasrulhazim/agent-skills/tree/main/skills/package-dev

## Install

```sh
agentstack add skill-nasrulhazim-agent-skills-package-dev
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Package Development Skill

Scaffold, test, document, and release production-quality Laravel/PHP packages — from initial
directory structure through Packagist publishing. Follows Laravel ecosystem conventions and
integrates with Orchestra Testbench for package testing.

## Command Reference

| Command | Description |
|---|---|
| `/package scaffold` | Generate complete package directory structure with all boilerplate files |
| `/package test` | Set up Pest test suite with Orchestra Testbench integration |
| `/package release` | Run release checklist: version bump, changelog, git tag, Packagist |
| `/package readme` | Generate professional README with badges, installation, usage, and testing sections |
| `/package upgrade` | Upgrade PHP/Laravel version constraints and dependencies |

---

## 1. `/package scaffold` — Generate Package Structure

### Step 1: Gather Package Information

Ask the user for:

- **Vendor name** — always ask, default: `cleaniquecoders`
- **Package name** — kebab-case, all lowercase (e.g. `laravel-helper`, `profile`)
- **Package type** — Laravel package or pure PHP package
- **Package description** (one-liner for composer.json)
- **PHP minimum version** (default: `^8.4`)
- **Laravel version constraint** (default: `^12.0`, Laravel packages only)
- **Namespace** (default: derived from vendor/package, e.g. `CleaniqueCoders\Profile`)
- **Features to include** (config, migrations, views, routes, commands — pick applicable ones)

If the user already provided context, extract what you can and only ask for what is missing.

### Skeleton Templates

Use Spatie's skeleton templates to scaffold the package:

- **Laravel package**: Clone from [spatie/package-skeleton-laravel](https://github.com/spatie/package-skeleton-laravel)
- **PHP package**: Clone from [spatie/package-skeleton-php](https://github.com/spatie/package-skeleton-php)

After cloning, run the skeleton's configure script to replace placeholders with the actual vendor name, package name, namespace, and author details.

### Step 2: Generate Directory Structure

Create the following structure:

```
packages/vendor/package-name/
├── src/
│   ├── PackageNameServiceProvider.php
│   ├── Facades/
│   │   └── PackageName.php
│   ├── Actions/
│   ├── Concerns/
│   └── Contracts/
├── config/
│   └── package-name.php
├── database/
│   ├── factories/
│   └── migrations/
├── resources/
│   └── views/
├── routes/
│   └── web.php
├── tests/
│   ├── Pest.php
│   ├── TestCase.php
│   └── Feature/
├── stubs/
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── composer.json
└── phpunit.xml
```

Only include directories for features the user selected. Always include `src/`, `tests/`,
`composer.json`, `README.md`, `CHANGELOG.md`, and `LICENSE`.

### Step 3: Generate composer.json

Read `references/package-structure.md` for the full template. Key sections:

```json
{
    "name": "vendor/package-name",
    "description": "Package description here",
    "keywords": ["laravel", "php"],
    "license": "MIT",
    "require": {
        "php": "^8.4",
        "illuminate/support": "^12.0"
    },
    "require-dev": {
        "orchestra/testbench": "^10.0",
        "pestphp/pest": "^3.0",
        "pestphp/pest-plugin-laravel": "^3.0",
        "laravel/pint": "^1.0"
    },
    "autoload": {
        "psr-4": {
            "Vendor\\PackageName\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Vendor\\PackageName\\Tests\\": "tests/"
        }
    },
    "extra": {
        "laravel": {
            "providers": [
                "Vendor\\PackageName\\PackageNameServiceProvider"
            ],
            "aliases": {
                "PackageName": "Vendor\\PackageName\\Facades\\PackageName"
            }
        }
    },
    "config": {
        "sort-packages": true,
        "allow-plugins": {
            "pestphp/pest-plugin": true
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}
```

### Step 4: Generate ServiceProvider

Read `references/package-structure.md` for the full ServiceProvider patterns. The provider must:

- Extend `Illuminate\Support\ServiceProvider`
- Use `register()` for bindings and merging config
- Use `boot()` for publishing assets, loading routes, views, migrations, and commands
- Include conditional `if ($this->app->runningInConsole())` blocks for publishable assets
- Group publishes with tags: `{package-name}-config`, `{package-name}-migrations`, etc.

### Step 5: Generate Facade

```php
 \Vendor\PackageName\Facades\PackageName::class,
        ];
    }

    protected function getEnvironmentSetUp($app): void
    {
        config()->set('database.default', 'testing');
        config()->set('database.connections.testing', [
            'driver' => 'sqlite',
            'database' => ':memory:',
            'prefix' => '',
        ]);
    }

    protected function defineDatabaseMigrations(): void
    {
        $this->loadMigrationsFrom(__DIR__ . '/../database/migrations');
    }
}
```

### Step 3: Generate Pest.php

```php
in('Feature');
```

### Step 4: Generate Starter Tests

Generate tests based on what the package provides:

| Package Feature | Test File | Key Assertions |
|---|---|---|
| ServiceProvider | `tests/Feature/ServiceProviderTest.php` | Provider loads, bindings resolve, config merges |
| Config | `tests/Feature/ConfigTest.php` | Config file publishable, default values correct |
| Migrations | `tests/Feature/MigrationTest.php` | Tables created, columns match expectations |
| Commands | `tests/Feature/CommandTest.php` | Command registered, executes without error |
| Routes | `tests/Feature/RouteTest.php` | Routes registered, middleware applied, responses correct |
| Facade | `tests/Feature/FacadeTest.php` | Facade resolves, methods callable |

### Step 5: Generate phpunit.xml

```xml

    
        
            tests/Feature
        
    
    
        
            src
        
    

```

---

## 3. `/package release` — Release Checklist

### Step 1: Pre-Release Validation

Run through these checks before releasing:

| Check | Command | Pass Condition |
|---|---|---|
| Tests pass | `composer test` or `./vendor/bin/pest` | Exit code 0, no failures |
| Code style | `./vendor/bin/pint --test` | No style violations |
| No uncommitted changes | `git status` | Clean working tree |
| README up to date | Manual review | Installation, usage, and changelog sections current |
| License file present | `ls LICENSE` | File exists |

### Step 2: Version Bump

Follow Semantic Versioning (SemVer):

| Change Type | Version Bump | Example |
|---|---|---|
| Bug fix, patch | PATCH | `1.0.0` -> `1.0.1` |
| New feature, backward-compatible | MINOR | `1.0.1` -> `1.1.0` |
| Breaking change | MAJOR | `1.1.0` -> `2.0.0` |

Update the version in `composer.json` if a `version` field exists (most packages rely on
git tags instead).

### Step 3: Update CHANGELOG.md

Follow Keep a Changelog format:

```markdown
# Changelog

All notable changes to this project will be documented in this file.

## [Unreleased]

## [1.1.0] - 2026-02-27

### Added
- New feature X for handling Y
- Support for Laravel 12

### Changed
- Updated minimum PHP version to 8.2

### Fixed
- Resolved issue with config publishing (#42)

## [1.0.0] - 2026-01-15

### Added
- Initial release
- Service provider with config publishing
- Facade support
- Migration publishing

[Unreleased]: https://github.com/vendor/package/compare/1.1.0...HEAD
[1.1.0]: https://github.com/vendor/package/compare/1.0.0...1.1.0
[1.0.0]: https://github.com/vendor/package/releases/tag/1.0.0
```

### Step 4: Commit and Tag

```bash
git add -A
git commit -m "chore: release 1.1.0"
git tag -a 1.1.0 -m "1.1.0"
git push origin main --tags
```

### Step 5: Packagist Publishing

- **First release:** Register at [packagist.org](https://packagist.org/packages/submit)
  with the GitHub repository URL
- **Subsequent releases:** Packagist auto-updates if the GitHub webhook is configured;
  otherwise run `curl -X POST https://packagist.org/api/update-package?username=USER&apiToken=TOKEN`
- Verify the release appears on Packagist within a few minutes

---

## 4. `/package readme` — README Generation

### Step 1: Scan Package

Read `composer.json`, `src/`, and `config/` to understand what the package provides.

### Step 2: Generate README Structure

```markdown
# Package Name

[](https://packagist.org/packages/vendor/package-name)
[](https://github.com/vendor/package-name/actions?query=workflow%3Arun-tests+branch%3Amain)
[](https://packagist.org/packages/vendor/package-name)

Short description of the package — one or two sentences.

## Installation

You can install the package via Composer:

\```bash
composer require vendor/package-name
\```

You can publish the config file with:

\```bash
php artisan vendor:publish --tag="package-name-config"
\```

Optionally, you can publish the migrations with:

\```bash
php artisan vendor:publish --tag="package-name-migrations"
\```

## Usage

\```php
use Vendor\PackageName\Facades\PackageName;

// Example usage
$result = PackageName::doSomething();
\```

## Testing

\```bash
composer test
\```

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

## Contributing

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

## Security Vulnerabilities

Please review [our security policy](../../security/policy) on how to report security
vulnerabilities.

## Credits

- [Author Name](https://github.com/author)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE) for more information.
```

### Step 3: Customise Sections

Based on the package scan:

| Package Feature | README Section to Add |
|---|---|
| Config file | "Configuration" section with key options documented |
| Migrations | "Database" section explaining tables created |
| Commands | "Commands" section listing artisan commands |
| Routes | "Routes" section with endpoint table |
| Views | "Views" section explaining publishable views |
| Events | "Events" section listing dispatched events |
| Middleware | "Middleware" section with registration instructions |

---

## 5. `/package upgrade` — Upgrade Dependencies

Bump PHP, Laravel, and ecosystem dependency version constraints in an existing package.

### Step 1: Read Current State

Parse `composer.json` for current constraints:

- `require.php`
- All `illuminate/*` packages
- `orchestra/testbench`
- `pestphp/pest-plugin-laravel`
- `laravel/pint`
- Any other Laravel-ecosystem dependencies

### Step 2: Check Dependency Availability

For each dependency being upgraded, verify the target version exists on Packagist:

- Use `composer show {package} --available` or check `https://packagist.org/packages/{vendor}/{package}` to confirm the target version/constraint is published
- Flag any dependency that does not yet have a compatible release for the target Laravel/PHP version
- If a dependency is not available, warn the user and suggest alternatives: wait for the release, find a fork, or drop the dependency

### Step 3: Show Current vs Target

Display a comparison table with availability status:

| Dependency | Current | Target | Available? |
|---|---|---|---|
| `php` | `^8.2` | `^8.4` | ✅ |
| `illuminate/support` | `^11.0` | `^12.0` | ✅ |
| `orchestra/testbench` | `^9.0` | `^10.0` | ✅ |
| `pestphp/pest-plugin-laravel` | `^2.0` | `^3.0` | ✅ |

### Step 4: Ask Target Versions

Confirm with the user before proceeding. Defaults:

- **PHP**: `^8.4`
- **Laravel**: `^12.0`
- **Testbench**: `^10.0`

### Step 5: Reference Upgrade Guide

Point the user to the official Laravel upgrade guide for breaking changes:

- `https://laravel.com/docs/{targetMajor}.x/upgrade`

For example, when upgrading to Laravel 12: `https://laravel.com/docs/12.x/upgrade`

### Step 6: Update composer.json

Bump version constraints for:

- `require.php`
- All `illuminate/*` packages in `require` and `require-dev`
- `orchestra/testbench`
- `pestphp/pest-plugin-laravel`
- `laravel/pint`
- Any other Laravel-ecosystem dev dependencies

### Step 7: Run Composer Update

```bash
composer update
```

If dependency resolution fails, report which packages conflict and suggest resolution steps.

### Step 8: Run Tests

```bash
composer test
```

Or `./vendor/bin/pest` if no `test` script is defined. Report any failures so the user can address breaking changes.

### Step 9: Update README

If the README contains version badges or a "Requirements" section referencing specific PHP/Laravel versions, update those to match the new constraints.

### Version Compatibility Matrix

| Laravel | PHP      | Testbench | Pest Plugin Laravel |
|---------|----------|-----------|---------------------|
| 12.x    | ^8.2     | ^10.0     | ^3.0                |
| 11.x    | ^8.2     | ^9.0      | ^2.0 / ^3.0         |
| 10.x    | ^8.1     | ^8.0      | ^2.0                |

---

## 6. Anti-Patterns to Avoid

| Anti-Pattern | Correct Approach |
|---|---|
| Hardcoding Laravel version in ServiceProvider | Use `illuminate/*` packages with version ranges |
| Registering everything in `boot()` | Use `register()` for bindings, `boot()` for bootstrapping |
| Missing `declare(strict_types=1)` | Include in every PHP file |
| No publish tags | Always tag publishable assets: `{package}-config`, `{package}-migrations` |
| Monolithic ServiceProvider | Extract to separate concerns if provider exceeds 100 lines |
| Testing against real database | Always use SQLite `:memory:` via Testbench |
| Missing `extra.laravel` in composer.json | Required for auto-discovery to work |
| No `.gitignore` for `vendor/` and `composer.lock` | Packages must ignore `composer.lock` (apps keep it) |

---

## Reference Files

| File | Read When |
|---|---|
| `references/package-structure.md` | Scaffolding package structure, ServiceProvider, Facade, and composer.json patterns |
| `references/testbench-patterns.md` | Setting up Orchestra Testbench, writing package tests |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [nasrulhazim](https://github.com/nasrulhazim)
- **Source:** [nasrulhazim/agent-skills](https://github.com/nasrulhazim/agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-nasrulhazim-agent-skills-package-dev
- Seller: https://agentstack.voostack.com/s/nasrulhazim
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
