feat(marketplace): command consolidation + 8 new plugins (v8.1.0 → v9.0.0) [BREAKING]

Phase 1b: Rename all ~94 commands across 12 plugins to /<noun> <action>
sub-command pattern. Git-flow consolidated from 8→5 commands (commit
variants absorbed into --push/--merge/--sync flags). Dispatch files,
name: frontmatter, and cross-reference updates for all plugins.

Phase 2: Design documents for 8 new plugins in docs/designs/.

Phase 3: Scaffold 8 new plugins — saas-api-platform, saas-db-migrate,
saas-react-platform, saas-test-pilot, data-seed, ops-release-manager,
ops-deploy-pipeline, debug-mcp. Each with plugin.json, commands, agents,
skills, README, and claude-md-integration. Marketplace grows from 12→20.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-06 14:52:11 -05:00
parent 5098422858
commit 2d51df7a42
321 changed files with 13582 additions and 1019 deletions

View File

@@ -0,0 +1,90 @@
---
name: faker-patterns
description: Realistic data generation patterns using faker providers with locale awareness
---
# Faker Patterns
## Purpose
Map schema column types and naming conventions to appropriate faker data generators. This skill ensures generated test data is realistic, locale-aware, and respects type constraints.
---
## Column Name to Provider Mapping
Use column name heuristics to select the most realistic faker provider:
| Column Name Pattern | Faker Provider | Example Output |
|---------------------|---------------|----------------|
| `*name`, `first_name` | `faker.name()` / `faker.first_name()` | "Alice Johnson" |
| `*last_name`, `surname` | `faker.last_name()` | "Rodriguez" |
| `*email` | `faker.email()` | "alice@example.com" |
| `*phone*`, `*tel*` | `faker.phone_number()` | "+1-555-0123" |
| `*address*`, `*street*` | `faker.street_address()` | "742 Evergreen Terrace" |
| `*city` | `faker.city()` | "Toronto" |
| `*state*`, `*province*` | `faker.state()` | "Ontario" |
| `*country*` | `faker.country()` | "Canada" |
| `*zip*`, `*postal*` | `faker.postcode()` | "M5V 2H1" |
| `*url*`, `*website*` | `faker.url()` | "https://example.com" |
| `*company*`, `*org*` | `faker.company()` | "Acme Corp" |
| `*title*`, `*subject*` | `faker.sentence(nb_words=5)` | "Updated quarterly report summary" |
| `*description*`, `*bio*`, `*body*` | `faker.paragraph()` | Multi-sentence text |
| `*created*`, `*updated*`, `*_at` | `faker.date_time_between(start_date='-2y')` | "2024-06-15T10:30:00" |
| `*date*`, `*dob*`, `*birth*` | `faker.date_of_birth(minimum_age=18)` | "1990-03-22" |
| `*price*`, `*amount*`, `*cost*` | `faker.pydecimal(min_value=0.01, max_value=9999.99)` | 49.99 |
| `*quantity*`, `*count*` | `faker.random_int(min=1, max=100)` | 7 |
| `*status*` | Random from enum or `["active", "inactive", "pending"]` | "active" |
| `*uuid*`, `*guid*` | `faker.uuid4()` | "550e8400-e29b-41d4-a716-446655440000" |
| `*ip*`, `*ip_address*` | `faker.ipv4()` | "192.168.1.42" |
| `*color*`, `*colour*` | `faker.hex_color()` | "#3498db" |
| `*password*`, `*hash*` | `faker.sha256()` | Hash string (never plaintext) |
| `*image*`, `*avatar*`, `*photo*` | `faker.image_url()` | "https://picsum.photos/200" |
| `*slug*` | `faker.slug()` | "updated-quarterly-report" |
| `*username*`, `*login*` | `faker.user_name()` | "alice_johnson42" |
## Type Fallback Mapping
When column name does not match any pattern, fall back to type-based generation:
| Canonical Type | Generator |
|----------------|-----------|
| `string` | `faker.pystr(max_chars=max_length)` |
| `integer` | `faker.random_int(min=0, max=2147483647)` |
| `float` | `faker.pyfloat(min_value=0, max_value=10000)` |
| `decimal` | `faker.pydecimal(left_digits=precision-scale, right_digits=scale)` |
| `boolean` | `faker.pybool()` |
| `datetime` | `faker.date_time_between(start_date='-2y', end_date='now')` |
| `date` | `faker.date_between(start_date='-2y', end_date='today')` |
| `uuid` | `faker.uuid4()` |
| `json` | `{"key": faker.word(), "value": faker.sentence()}` |
## Locale Support
Supported locales affect names, addresses, phone formats, and postal codes:
| Locale | Names | Addresses | Phone | Currency |
|--------|-------|-----------|-------|----------|
| `en_US` | English names | US addresses | US format | USD |
| `en_CA` | English names | Canadian addresses | CA format | CAD |
| `en_GB` | English names | UK addresses | UK format | GBP |
| `pt_BR` | Portuguese names | Brazilian addresses | BR format | BRL |
| `fr_FR` | French names | French addresses | FR format | EUR |
| `de_DE` | German names | German addresses | DE format | EUR |
| `ja_JP` | Japanese names | Japanese addresses | JP format | JPY |
| `es_ES` | Spanish names | Spanish addresses | ES format | EUR |
Default locale: `en_US`. Override per-profile or per-command with `--locale`.
## Edge Case Values
Include at configurable ratio (default 10%):
| Type | Edge Cases |
|------|------------|
| `string` | Empty string `""`, max-length string, unicode characters, emoji, SQL special chars `'; DROP TABLE --` |
| `integer` | 0, -1, MAX_INT, MIN_INT |
| `float` | 0.0, -0.0, very small (0.0001), very large (999999.99) |
| `date` | Today, yesterday, epoch (1970-01-01), leap day (2024-02-29) |
| `boolean` | null (if nullable) |
| `email` | Plus-addressed `user+tag@example.com`, long domain, subdomain email |

View File

@@ -0,0 +1,116 @@
---
name: profile-management
description: Seed profile definitions with row counts, edge case ratios, and custom value overrides
---
# Profile Management
## Purpose
Define and manage reusable seed data profiles that control how much data is generated, what edge cases are included, and what custom overrides apply. Profiles enable reproducible, consistent test data across environments.
---
## Profile Storage
Profiles are stored in `seed-profiles.json` in the configured output directory (default: `seeds/` or `fixtures/`).
## Profile Schema
```json
{
"profiles": [
{
"name": "profile-name",
"description": "Human-readable description",
"default_rows": 100,
"table_overrides": {
"table_name": 200
},
"edge_case_ratio": 0.1,
"null_ratio": 0.05,
"locale": "en_US",
"seed_value": 42,
"custom_values": {
"table.column": ["value1", "value2", "value3"]
},
"relationship_density": {
"many_to_many": 0.3,
"self_ref_max_depth": 3
}
}
],
"default_profile": "medium"
}
```
## Field Definitions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Unique profile identifier (lowercase, hyphens allowed) |
| `description` | string | No | What this profile is for |
| `default_rows` | integer | Yes | Row count for tables without explicit override |
| `table_overrides` | object | No | Per-table row count overrides |
| `edge_case_ratio` | float | No | Fraction of rows with edge case values (0.0 to 1.0, default 0.1) |
| `null_ratio` | float | No | Fraction of nullable columns set to null (0.0 to 1.0, default 0.05) |
| `locale` | string | No | Faker locale for name/address generation (default "en_US") |
| `seed_value` | integer | No | Random seed for reproducibility (default: hash of profile name) |
| `custom_values` | object | No | Column-specific value pools (table.column -> array of values) |
| `relationship_density` | object | No | Controls many-to-many fill ratio and self-referential depth |
## Built-in Profiles
### small
- `default_rows`: 10
- `edge_case_ratio`: 0.0
- `null_ratio`: 0.0
- Use case: unit tests, schema validation, quick smoke tests
- Characteristics: minimal data, no edge cases, all required fields populated
### medium
- `default_rows`: 100
- `edge_case_ratio`: 0.1
- `null_ratio`: 0.05
- Use case: development, manual testing, demo environments
- Characteristics: realistic volume, occasional edge cases, some nulls
### large
- `default_rows`: 1000
- `edge_case_ratio`: 0.05
- `null_ratio`: 0.03
- Use case: performance testing, pagination testing, stress testing
- Characteristics: high volume, lower edge case ratio to avoid noise
## Custom Value Overrides
Override the faker generator for specific columns with a weighted value pool:
```json
{
"custom_values": {
"users.role": ["user", "user", "user", "admin"],
"orders.status": ["completed", "completed", "pending", "cancelled", "refunded"],
"products.currency": ["USD"]
}
}
```
Values are selected randomly with replacement. Duplicate entries in the array increase that value's probability (e.g., "user" appears 3x = 75% probability).
## Profile Operations
### Resolution Order
When determining row count for a table:
1. Command-line `--rows` flag (highest priority)
2. Profile `table_overrides` for that specific table
3. Profile `default_rows`
4. Built-in default: 100
### Validation Rules
- Profile name must be unique within `seed-profiles.json`
- `default_rows` must be >= 1
- `edge_case_ratio` must be between 0.0 and 1.0
- `null_ratio` must be between 0.0 and 1.0
- Custom value arrays must not be empty
- Cannot delete the last remaining profile

View File

@@ -0,0 +1,118 @@
---
name: relationship-resolution
description: Foreign key resolution, dependency ordering, and circular dependency handling for seed data
---
# Relationship Resolution
## Purpose
Determine the correct order for generating and inserting seed data across tables with foreign key dependencies. Handle edge cases including circular dependencies, self-referential relationships, and many-to-many through tables.
---
## Dependency Graph Construction
### Step 1: Extract Foreign Keys
For each table, identify all columns with foreign key constraints:
- Direct FK references to other tables
- Self-referential FKs (same table)
- Composite FKs spanning multiple columns
### Step 2: Build Directed Graph
- Each table is a node
- Each FK creates a directed edge: child -> parent (child depends on parent)
- Self-referential edges are noted but excluded from ordering (handled separately)
### Step 3: Topological Sort
- Apply topological sort to determine insertion order
- Tables with no dependencies come first
- Tables depending on others come after their dependencies
- Result: ordered list where every table's dependencies appear before it
## Insertion Order Example
Given schema:
```
users (no FK)
categories (no FK)
products (FK -> categories)
orders (FK -> users)
order_items (FK -> orders, FK -> products)
reviews (FK -> users, FK -> products)
```
Insertion order: `users, categories, products, orders, order_items, reviews`
Deletion order (reverse): `reviews, order_items, orders, products, categories, users`
## Circular Dependency Handling
When topological sort detects a cycle:
### Strategy 1: Nullable FK Deferral
If one FK in the cycle is nullable:
1. Insert rows with nullable FK set to NULL
2. Complete the cycle for the other table
3. UPDATE the nullable FK to point to the now-existing rows
Example: `departments.manager_id -> employees`, `employees.department_id -> departments`
1. Insert departments with `manager_id = NULL`
2. Insert employees referencing departments
3. UPDATE departments to set `manager_id` to an employee
### Strategy 2: Deferred Constraints
If database supports deferred constraints (PostgreSQL):
1. Set FK constraints to DEFERRED within transaction
2. Insert all rows in any order
3. Constraints checked at COMMIT time
### Strategy 3: Two-Pass Generation
If neither strategy works:
1. First pass: generate all rows without cross-cycle FK values
2. Second pass: update FK values to reference generated rows from the other table
## Self-Referential Relationships
Common pattern: `employees.manager_id -> employees.id`
### Generation Strategy
1. Generate root rows first (manager_id = NULL) — these are top-level managers
2. Generate second tier referencing root rows
3. Generate remaining rows referencing any previously generated row
4. Depth distribution controlled by profile (default: max depth 3, pyramid shape)
### Configuration
```json
{
"self_ref_null_ratio": 0.1,
"self_ref_max_depth": 3,
"self_ref_distribution": "pyramid"
}
```
## Many-to-Many Through Tables
Detection: a table with exactly two FK columns and no non-FK data columns (excluding PK and timestamps).
### Generation Strategy
1. Generate both parent tables first
2. Generate through table rows pairing random parents
3. Respect uniqueness on the (FK1, FK2) composite — no duplicate pairings
4. Density controlled by profile: sparse (10% of possible pairs), medium (30%), dense (60%)
## Deletion Order
When `--clean` is specified for `/seed apply`:
1. Reverse the insertion order
2. TRUNCATE or DELETE in this order to avoid FK violations
3. For circular dependencies: disable FK checks, truncate, re-enable (with user confirmation)
## Error Handling
| Scenario | Response |
|----------|----------|
| Unresolvable cycle (no nullable FKs, no deferred constraints) | FAIL: report cycle, suggest schema modification |
| Missing parent table in schema | FAIL: report orphaned FK reference |
| FK references non-existent column | FAIL: report schema inconsistency |
| Through table detection false positive | WARN: ask user to confirm junction table identification |

View File

@@ -0,0 +1,81 @@
---
name: schema-inference
description: Infer data types, constraints, and relationships from ORM models or raw SQL DDL
---
# Schema Inference
## Purpose
Parse and normalize schema definitions from multiple ORM dialects into a unified internal representation. This skill enables data generation and validation commands to work across SQLAlchemy, Prisma, Django ORM, and raw SQL DDL without dialect-specific logic in every command.
---
## Supported Schema Sources
| Source | Detection | File Patterns |
|--------|-----------|---------------|
| SQLAlchemy | `from sqlalchemy import`, `Column(`, `mapped_column(` | `models.py`, `models/*.py` |
| Prisma | `model` blocks with `@id`, `@relation` | `prisma/schema.prisma` |
| Django ORM | `from django.db import models`, `models.CharField` | `models.py` with Django imports |
| Raw SQL DDL | `CREATE TABLE` statements | `*.sql`, `schema.sql`, `migrations/*.sql` |
| JSON Schema | `"type": "object"`, `"properties":` | `*.schema.json` |
## Type Normalization
Map dialect-specific types to a canonical set:
| Canonical Type | SQLAlchemy | Prisma | Django | SQL |
|----------------|------------|--------|--------|-----|
| `string` | `String(N)`, `Text` | `String` | `CharField`, `TextField` | `VARCHAR(N)`, `TEXT` |
| `integer` | `Integer`, `BigInteger`, `SmallInteger` | `Int`, `BigInt` | `IntegerField`, `BigIntegerField` | `INT`, `BIGINT`, `SMALLINT` |
| `float` | `Float`, `Numeric` | `Float` | `FloatField` | `FLOAT`, `REAL`, `DOUBLE` |
| `decimal` | `Numeric(P,S)` | `Decimal` | `DecimalField` | `DECIMAL(P,S)`, `NUMERIC(P,S)` |
| `boolean` | `Boolean` | `Boolean` | `BooleanField` | `BOOLEAN`, `BIT` |
| `datetime` | `DateTime` | `DateTime` | `DateTimeField` | `TIMESTAMP`, `DATETIME` |
| `date` | `Date` | `DateTime` | `DateField` | `DATE` |
| `uuid` | `UUID` | `String @default(uuid())` | `UUIDField` | `UUID` |
| `json` | `JSON` | `Json` | `JSONField` | `JSON`, `JSONB` |
| `enum` | `Enum(...)` | `enum` block | `choices=` | `ENUM(...)`, `CHECK IN (...)` |
## Constraint Extraction
For each column, extract:
- **nullable**: Whether NULL values are allowed (default: true unless PK or explicit NOT NULL)
- **unique**: Whether values must be unique
- **max_length**: For string types, the maximum character length
- **precision/scale**: For decimal types
- **default**: Default value expression
- **check**: CHECK constraint expressions (e.g., `age >= 0`)
- **primary_key**: Whether this column is part of the primary key
## Relationship Extraction
Identify foreign key relationships:
- **parent_table**: The referenced table
- **parent_column**: The referenced column (usually PK)
- **on_delete**: CASCADE, SET NULL, RESTRICT, NO ACTION
- **self_referential**: True if FK references same table
- **many_to_many**: Detected from junction/through tables with two FKs and no additional non-FK columns
## Output Format
Internal representation used by other skills:
```json
{
"tables": {
"users": {
"columns": {
"id": {"type": "integer", "primary_key": true, "nullable": false},
"email": {"type": "string", "max_length": 255, "unique": true, "nullable": false},
"name": {"type": "string", "max_length": 100, "nullable": false},
"manager_id": {"type": "integer", "nullable": true, "foreign_key": {"table": "users", "column": "id"}}
},
"relationships": [
{"type": "self_referential", "column": "manager_id", "references": "users.id"}
]
}
}
}
```

View File

@@ -0,0 +1,27 @@
# Visual Header Skill
Standard visual header for data-seed commands.
## Header Template
```
+----------------------------------------------------------------------+
| DATA-SEED - [Context] |
+----------------------------------------------------------------------+
```
## Context Values by Command
| Command | Context |
|---------|---------|
| `/seed setup` | Setup Wizard |
| `/seed generate` | Generate |
| `/seed apply` | Apply |
| `/seed profile` | Profile Management |
| `/seed validate` | Validate |
| Agent mode (seed-generator) | Data Generation |
| Agent mode (seed-validator) | Validation |
## Usage
Display header at the start of every command response before proceeding with the operation.