@kennethsolomon/shipkit 3.19.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +36 -4
  2. package/package.json +1 -1
  3. package/skills/sk:brainstorming/SKILL.md +19 -128
  4. package/skills/sk:debug/SKILL.md +44 -111
  5. package/skills/sk:e2e/SKILL.md +45 -97
  6. package/skills/sk:features/SKILL.md +44 -99
  7. package/skills/sk:frontend-design/SKILL.md +16 -32
  8. package/skills/sk:laravel-init/SKILL.md +8 -7
  9. package/skills/sk:laravel-new/SKILL.md +1 -0
  10. package/skills/sk:lint/SKILL.md +42 -62
  11. package/skills/sk:mvp/SKILL.md +81 -134
  12. package/skills/sk:perf/SKILL.md +24 -43
  13. package/skills/sk:review/SKILL.md +57 -93
  14. package/skills/sk:security-check/SKILL.md +37 -43
  15. package/skills/sk:seo-audit/SKILL.md +75 -96
  16. package/skills/sk:setup-claude/SKILL.md +154 -0
  17. package/skills/sk:setup-claude/references/skill-profiles.md +223 -0
  18. package/skills/sk:setup-claude/scripts/__pycache__/apply_setup_claude.cpython-314.pyc +0 -0
  19. package/skills/sk:setup-claude/scripts/apply_setup_claude.py +110 -10
  20. package/skills/sk:setup-claude/templates/.claude/rules/laravel.md.template +14 -0
  21. package/skills/sk:setup-claude/templates/CLAUDE.md.template +102 -247
  22. package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +1 -1
  23. package/skills/sk:setup-claude/templates/commands/execute-plan.md.template +1 -1
  24. package/skills/sk:setup-claude/templates/commands/finish-feature.md.template +1 -1
  25. package/skills/sk:setup-claude/templates/commands/security-check.md.template +1 -1
  26. package/skills/sk:setup-claude/templates/commands/write-plan.md.template +1 -1
  27. package/skills/sk:setup-claude/tests/__pycache__/test_apply_setup_claude.cpython-314.pyc +0 -0
  28. package/skills/sk:setup-claude/tests/test_apply_setup_claude.py +267 -0
  29. package/skills/sk:setup-optimizer/SKILL.md +101 -17
  30. package/skills/sk:skill-creator/SKILL.md +115 -226
  31. package/skills/sk:website/SKILL.md +81 -149
  32. package/skills/sk:write-tests/SKILL.md +44 -110
@@ -0,0 +1,223 @@
1
+ # ShipKit Skill Profiles — Stack-Based Filtering
2
+
3
+ **Last Updated:** 2026-03-30
4
+ **Total Skills:** 44 | **Agents:** 13 | **Rules:** 6 | **Project MCP:** 1
5
+
6
+ This file is the source of truth for which skills, agents, rules, and project-level MCP servers get installed per project. Read by `sk:setup-claude` (initial setup) and `sk:setup-optimizer` (ongoing sync).
7
+
8
+ ---
9
+
10
+ ## Universal Skills (always installed — 25 skills)
11
+
12
+ | Skill | Purpose |
13
+ |-------|---------|
14
+ | sk:start | Smart entry point — classifies task, routes to workflow |
15
+ | sk:context | Load project context + session brief |
16
+ | sk:brainstorming | Explore requirements before implementation |
17
+ | sk:write-plan | Decision-complete plan into todo.md |
18
+ | sk:execute-plan | Implement tasks in batches with progress logging |
19
+ | sk:write-tests | TDD: write failing tests before implementation |
20
+ | sk:test | Run all test suites, verify 100% coverage |
21
+ | sk:lint | Auto-detect and run all linters |
22
+ | sk:debug | Structured bug investigation |
23
+ | sk:review | 7-dimension self-review |
24
+ | sk:smart-commit | Conventional commit with approval |
25
+ | sk:gates | All quality gates in parallel batches |
26
+ | sk:safety-guard | Protect against destructive operations |
27
+ | sk:scope-check | Detect scope creep vs plan |
28
+ | sk:save-session | Save session state for continuity |
29
+ | sk:resume-session | Restore previously saved session |
30
+ | sk:learn | Extract reusable patterns from session |
31
+ | sk:retro | Post-ship retrospective |
32
+ | sk:health | Harness self-audit scorecard |
33
+ | sk:context-budget | Audit context window token consumption |
34
+ | sk:setup-claude | Bootstrap project scaffolding |
35
+ | sk:setup-optimizer | Diagnose + update workflow + enrich CLAUDE.md |
36
+ | sk:release | Version bump + changelog + tag |
37
+ | sk:fast-track | Abbreviated workflow for small changes |
38
+ | sk:skill-creator | Create or modify skills |
39
+
40
+ ---
41
+
42
+ ## Stack-Specific Skills
43
+
44
+ ### Laravel (+4 skills)
45
+
46
+ | Skill | Purpose |
47
+ |-------|---------|
48
+ | sk:laravel-new | Scaffold fresh Laravel app |
49
+ | sk:laravel-init | Configure existing Laravel project |
50
+ | sk:laravel-deploy | Deploy to Laravel Cloud |
51
+ | sk:schema-migrate | Multi-ORM schema change analysis |
52
+
53
+ ### Web (+5 skills)
54
+
55
+ | Skill | Purpose |
56
+ |-------|---------|
57
+ | sk:frontend-design | UI mockup before implementation |
58
+ | sk:accessibility | WCAG 2.1 AA audit |
59
+ | sk:seo-audit | SEO audit (source + dev server) |
60
+ | sk:website | Build multi-page marketing website |
61
+ | sk:mvp | Generate MVP with landing page + app |
62
+
63
+ ### Database (+1 skill)
64
+
65
+ | Skill | Purpose |
66
+ |-------|---------|
67
+ | sk:schema-migrate | Multi-ORM schema change analysis |
68
+
69
+ ### API (+2 skills)
70
+
71
+ | Skill | Purpose |
72
+ |-------|---------|
73
+ | sk:api-design | Design API contracts before implementation |
74
+ | sk:team | Parallel domain agents (BE + FE + QA) |
75
+
76
+ ### Mobile (exclude from web)
77
+
78
+ No additional skills. **Exclude:** sk:e2e (Playwright), sk:seo-audit, sk:accessibility, sk:website.
79
+
80
+ ---
81
+
82
+ ## Opt-In Skills (manual activation only — 8 skills)
83
+
84
+ | Skill | Purpose | When to activate |
85
+ |-------|---------|-----------------|
86
+ | sk:autopilot | Hands-free workflow, all 8 steps | Well-defined tasks, minimal steering |
87
+ | sk:eval | Run evaluations for agent reliability | Eval-driven development |
88
+ | sk:ci | Set up GitHub Actions or GitLab CI | First-time CI setup |
89
+ | sk:reverse-doc | Generate docs from existing code | Onboarding, formalizing prototypes |
90
+ | sk:features | Sync feature specs with implementation | Feature spec maintenance |
91
+ | sk:e2e | E2E behavioral verification | Web projects with Playwright/Cypress |
92
+ | sk:dashboard | Workflow Kanban board (localhost) | Multi-worktree progress tracking |
93
+ | sk:plugin | Package skills as distributable plugin | Team skill sharing |
94
+
95
+ ---
96
+
97
+ ## Quality Gate Skills (part of sk:gates — always installed)
98
+
99
+ | Skill | Gate role |
100
+ |-------|----------|
101
+ | sk:perf | Performance audit |
102
+ | sk:security-check | OWASP security audit |
103
+
104
+ These are installed universally because they run inside `sk:gates`. Perf auto-skips if no frontend+DB keywords. Security always runs.
105
+
106
+ ---
107
+
108
+ ## Stack Detection Rules
109
+
110
+ | Priority | Signal | Detected Stack | Capabilities |
111
+ |----------|--------|---------------|-------------|
112
+ | 1 | `composer.json` + `laravel/framework` | laravel | web, database, api |
113
+ | 2 | `package.json` + `next` | nextjs | web |
114
+ | 3 | `package.json` + `nuxt` | nuxt | web |
115
+ | 4 | `package.json` + `react` (no next) | react | web |
116
+ | 5 | `package.json` + `vue` (no nuxt) | vue | web |
117
+ | 6 | `package.json` + `svelte` | svelte | web |
118
+ | 7 | `app.json` or `app.config.ts` | expo | mobile |
119
+ | 8 | `react-native.config.js` | react-native | mobile |
120
+ | 9 | `pubspec.yaml` | flutter | mobile |
121
+ | 10 | `package.json` + `express` | express | api |
122
+ | 11 | `go.mod` | go | api |
123
+ | 12 | `Cargo.toml` | rust | api |
124
+ | 13 | `pyproject.toml` / `requirements.txt` | python | api |
125
+ | 14 | `Gemfile` + `rails` | rails | web, database, api |
126
+
127
+ ### Capability → Add-on mapping
128
+
129
+ | Capability | Add-on skills |
130
+ |-----------|---------------|
131
+ | web | sk:frontend-design, sk:accessibility, sk:seo-audit, sk:website, sk:mvp |
132
+ | database | sk:schema-migrate |
133
+ | api | sk:api-design, sk:team |
134
+ | laravel | sk:laravel-new, sk:laravel-init, sk:laravel-deploy |
135
+ | mobile | Exclude: sk:e2e, sk:seo-audit, sk:accessibility, sk:website |
136
+
137
+ ### Database sub-detection (within any stack)
138
+
139
+ | Signal | ORM |
140
+ |--------|-----|
141
+ | `prisma/schema.prisma` | Prisma → add `database` capability |
142
+ | `drizzle.config.ts` / `.js` | Drizzle → add `database` capability |
143
+ | `database/migrations/` (Laravel) | Laravel migrations → add `database` capability |
144
+ | `alembic/` | SQLAlchemy → add `database` capability |
145
+ | `db/migrate/` (Rails) | Rails migrations → add `database` capability |
146
+
147
+ ---
148
+
149
+ ## Agent → Stack Mapping
150
+
151
+ | Agent | Stacks | Notes |
152
+ |-------|--------|-------|
153
+ | architect | all | System design, universal |
154
+ | backend-dev | laravel, express, go, python, rust, rails | Backend implementation |
155
+ | frontend-dev | react, nextjs, vue, nuxt, svelte | Frontend implementation |
156
+ | mobile-dev | expo, react-native, flutter | Mobile-specific |
157
+ | database-architect | any with `database` capability | Schema design, migrations |
158
+ | qa-engineer | all | E2E test scenarios, universal |
159
+ | debugger | all | Bug investigation, universal |
160
+ | code-reviewer | all | Code quality review, universal |
161
+ | security-reviewer | all | OWASP audit, universal |
162
+ | performance-optimizer | all | Performance analysis, universal |
163
+ | refactor-specialist | all | Safe refactoring, universal |
164
+ | tech-writer | all | Documentation, universal |
165
+ | devops-engineer | all | CI/CD, deployment, universal |
166
+
167
+ ---
168
+
169
+ ## Rule → Stack Mapping
170
+
171
+ | Rule | Applies to stacks | Path patterns |
172
+ |------|------------------|---------------|
173
+ | tests.md | all | `tests/**`, `**/*.test.*`, `**/*.spec.*` |
174
+ | api.md | laravel, express, go, python, rails | `routes/api.php`, `**/controllers/**`, `src/api/**` |
175
+ | laravel.md | laravel | `app/**/*.php`, `routes/**`, `config/**` |
176
+ | react.md | react, nextjs | `**/*.{tsx,jsx}`, `resources/js/**` |
177
+ | vue.md | vue, nuxt | `**/*.vue`, `resources/js/**` |
178
+ | migrations.md | any with `database` capability | `database/migrations/**`, `prisma/**`, `db/migrate/**` |
179
+
180
+ ---
181
+
182
+ ## Project-Level MCP Server → Stack Mapping
183
+
184
+ MCP servers configured in the project's `.mcp.json` (not global `~/.mcp.json`). Managed by `sk:setup-claude` (initial setup) and `sk:setup-optimizer` (ongoing sync).
185
+
186
+ | MCP Server | Stack | Command | Purpose |
187
+ |-----------|-------|---------|---------|
188
+ | laravel-boost | laravel | `php artisan boost:mcp` (or `vendor/bin/sail artisan boost:mcp` for Sail) | Database schema, queries, docs search, logs, browser errors |
189
+
190
+ **Sync rules:**
191
+ - **Add** to `.mcp.json` when stack matches and entry is missing
192
+ - **Remove** from `.mcp.json` when stack no longer matches (e.g., project switched from Laravel to Next.js)
193
+ - **Update** existing entry if command is stale (e.g., Sail added/removed — switch between `php` and `vendor/bin/sail`)
194
+ - Never touch MCP entries not in this table (user-added entries are preserved)
195
+ - Sail detection: use `vendor/bin/sail` command variant if `vendor/bin/sail` exists
196
+ - **Ownership:** Project-level MCP is managed by `sk:setup-claude` (initial) and `sk:setup-optimizer` Step 0.5 (ongoing). Step 1.7 handles only global MCP.
197
+
198
+ ---
199
+
200
+ ## Installation Formula
201
+
202
+ For a given project with detected `stack` and `capabilities`:
203
+
204
+ ```
205
+ installed_skills = universal_skills
206
+ + capability_add_ons(capabilities)
207
+ + config.skills.extra
208
+ - config.skills.disabled
209
+ - mobile_exclusions (if mobile stack)
210
+
211
+ installed_agents = universal_agents
212
+ + stack_specific_agents(stack)
213
+ - agents not matching any detected stack
214
+
215
+ installed_rules = universal_rules (tests.md)
216
+ + stack_matching_rules(stack, capabilities)
217
+
218
+ project_mcp = stack_matching_mcp(stack)
219
+ # Add matching entries to .mcp.json
220
+ # Remove non-matching entries from .mcp.json (only managed entries — never touch user-added)
221
+ ```
222
+
223
+ User overrides (`extra`, `disabled`) are never touched by auto-detection.
@@ -58,6 +58,14 @@ def _has_dep(pkg: dict, name: str) -> bool:
58
58
  return name in deps
59
59
 
60
60
 
61
+ def _has_composer_dep(composer: dict, name: str) -> bool:
62
+ """Check if a Composer package is in require or require-dev."""
63
+ deps = {}
64
+ for key in ("require", "require-dev"):
65
+ deps.update(composer.get(key, {}) or {})
66
+ return name in deps
67
+
68
+
61
69
  def _any_dep_prefix(pkg: dict, prefix: str) -> bool:
62
70
  deps = {}
63
71
  for key in ("dependencies", "devDependencies", "peerDependencies", "optionalDependencies"):
@@ -107,13 +115,16 @@ def _write_cached_detection(repo_root: Path, detection: Detection) -> None:
107
115
 
108
116
  def detect(repo_root: Path) -> Detection:
109
117
  package_json = _read_json(repo_root / "package.json") or {}
118
+ composer_json = _read_json(repo_root / "composer.json") or {}
110
119
  scripts = (package_json.get("scripts") or {}) if isinstance(package_json, dict) else {}
111
120
 
112
121
  project_name = str(package_json.get("name") or repo_root.name)
113
122
  description = str(package_json.get("description") or "Project instructions for Claude Code.")
114
123
 
115
- # Language
116
- if (repo_root / "tsconfig.json").exists() or _has_dep(package_json, "typescript"):
124
+ # Language — composer.json with laravel/framework takes priority over package.json
125
+ if _has_composer_dep(composer_json, "laravel/framework"):
126
+ language = "PHP"
127
+ elif (repo_root / "tsconfig.json").exists() or _has_dep(package_json, "typescript"):
117
128
  language = "TypeScript"
118
129
  elif (repo_root / "package.json").exists():
119
130
  language = "JavaScript"
@@ -129,7 +140,21 @@ def detect(repo_root: Path) -> Detection:
129
140
  language = "Unknown"
130
141
 
131
142
  # Framework (keep simple; expand later)
132
- if _has_dep(package_json, "next"):
143
+ is_laravel = _has_composer_dep(composer_json, "laravel/framework")
144
+ if is_laravel:
145
+ # Sub-detect Laravel stack flavor
146
+ if _has_composer_dep(composer_json, "inertiajs/inertia-laravel"):
147
+ if _has_dep(package_json, "react"):
148
+ framework = "Laravel (Inertia + React)"
149
+ elif _has_dep(package_json, "vue"):
150
+ framework = "Laravel (Inertia + Vue)"
151
+ else:
152
+ framework = "Laravel (Inertia)"
153
+ elif _has_composer_dep(composer_json, "livewire/livewire"):
154
+ framework = "Laravel (Livewire)"
155
+ else:
156
+ framework = "Laravel (API)"
157
+ elif _has_dep(package_json, "next"):
133
158
  framework = "Next.js (App Router)"
134
159
  elif _has_dep(package_json, "react"):
135
160
  framework = "React"
@@ -139,7 +164,9 @@ def detect(repo_root: Path) -> Detection:
139
164
  framework = "Unknown"
140
165
 
141
166
  # Database / ORM
142
- if _has_dep(package_json, "drizzle-orm"):
167
+ if is_laravel and (repo_root / "database" / "migrations").exists():
168
+ database = "Eloquent ORM"
169
+ elif _has_dep(package_json, "drizzle-orm"):
143
170
  if _has_dep(package_json, "better-sqlite3"):
144
171
  database = "Drizzle ORM + SQLite"
145
172
  elif _has_dep(package_json, "pg"):
@@ -165,7 +192,9 @@ def detect(repo_root: Path) -> Detection:
165
192
  ui = "Unknown"
166
193
 
167
194
  # Testing
168
- if _has_dep(package_json, "vitest"):
195
+ if _has_composer_dep(composer_json, "pestphp/pest"):
196
+ testing = "Pest"
197
+ elif _has_dep(package_json, "vitest"):
169
198
  testing = "Vitest"
170
199
  elif _has_dep(package_json, "jest"):
171
200
  testing = "Jest"
@@ -190,10 +219,16 @@ def detect(repo_root: Path) -> Detection:
190
219
  else:
191
220
  browser_automation = "None"
192
221
 
193
- dev_cmd = scripts.get("dev") and "npm run dev" or "npm run dev"
194
- build_cmd = scripts.get("build") and "npm run build" or "npm run build"
195
- lint_cmd = scripts.get("lint") and "npm run lint" or "npm run lint"
196
- test_cmd = scripts.get("test") and "npm test" or "npm test"
222
+ if is_laravel:
223
+ dev_cmd = "php artisan serve"
224
+ build_cmd = "npm run build"
225
+ lint_cmd = "vendor/bin/pint"
226
+ test_cmd = "vendor/bin/pest"
227
+ else:
228
+ dev_cmd = scripts.get("dev") and "npm run dev" or "npm run dev"
229
+ build_cmd = scripts.get("build") and "npm run build" or "npm run build"
230
+ lint_cmd = scripts.get("lint") and "npm run lint" or "npm run lint"
231
+ test_cmd = scripts.get("test") and "npm test" or "npm test"
197
232
 
198
233
  typo_dir = repo_root / ".claude" / "docs" / "achritectural_change_log"
199
234
  correct_dir = repo_root / ".claude" / "docs" / "architectural_change_log"
@@ -413,7 +448,7 @@ def _rules_filter(detection: Detection):
413
448
  def _filter(filename: str) -> bool:
414
449
  if filename in always:
415
450
  return True
416
- if filename == "laravel.md.template" and "Laravel" in detection.framework:
451
+ if filename == "laravel.md.template" and detection.framework.startswith("Laravel"):
417
452
  return True
418
453
  if filename == "react.md.template" and (
419
454
  "React" in detection.framework or detection.framework == "Next.js (App Router)"
@@ -424,6 +459,67 @@ def _rules_filter(detection: Detection):
424
459
  return _filter
425
460
 
426
461
 
462
+ # Stack-conditional MCP server mapping (managed entries only)
463
+ _MANAGED_MCP_SERVERS: Dict[str, dict] = {
464
+ "laravel-boost": {
465
+ "stack_prefix": "Laravel",
466
+ "command": "php",
467
+ "args": ["artisan", "boost:mcp"],
468
+ "sail_command": "vendor/bin/sail",
469
+ },
470
+ }
471
+
472
+
473
+ def _deploy_project_mcp(
474
+ repo_root: Path,
475
+ detection: Detection,
476
+ *,
477
+ dry_run: bool,
478
+ ) -> List[tuple]:
479
+ """Add/remove/update managed MCP entries in .mcp.json based on detected stack."""
480
+ mcp_path = repo_root / ".mcp.json"
481
+ results: List[tuple] = []
482
+
483
+ existing = _read_json(mcp_path) or {}
484
+ servers = existing.get("mcpServers", {})
485
+ changed = False
486
+
487
+ for name, config in _MANAGED_MCP_SERVERS.items():
488
+ stack_matches = detection.framework.startswith(config["stack_prefix"])
489
+ use_sail = (repo_root / "vendor" / "bin" / "sail").exists()
490
+ command = config["sail_command"] if use_sail else config["command"]
491
+ expected_entry = {"command": command, "args": config["args"], "env": {}}
492
+
493
+ if stack_matches:
494
+ if name not in servers:
495
+ servers[name] = expected_entry
496
+ changed = True
497
+ elif servers[name].get("command") != command:
498
+ # Sail status changed — update command
499
+ servers[name]["command"] = command
500
+ changed = True
501
+ else:
502
+ if name in servers:
503
+ del servers[name]
504
+ changed = True
505
+
506
+ if not changed:
507
+ results.append(("skipped", mcp_path))
508
+ return results
509
+
510
+ if dry_run:
511
+ action = "updated" if mcp_path.exists() else "created"
512
+ results.append((action, mcp_path))
513
+ return results
514
+
515
+ existing["mcpServers"] = servers
516
+ mcp_path.parent.mkdir(parents=True, exist_ok=True)
517
+ mcp_path.write_text(json.dumps(existing, indent=2) + "\n", encoding="utf-8")
518
+ action = "updated" if mcp_path.exists() else "created"
519
+ results.append((action, mcp_path))
520
+ return results
521
+
522
+
427
523
  def apply(
428
524
  repo_root: Path,
429
525
  skill_root: Path,
@@ -571,6 +667,10 @@ def apply(
571
667
  action_sl = "created"
572
668
  _collect_results([(action_sl, statusline_dest)], repo_root, created, updated, skipped)
573
669
 
670
+ # --- Deploy project-level .mcp.json (stack-conditional) ---
671
+ mcp_results = _deploy_project_mcp(repo_root, detection, dry_run=dry_run)
672
+ _collect_results(mcp_results, repo_root, created, updated, skipped)
673
+
574
674
  if dry_run:
575
675
  print("setup-claude dry-run complete (no files written)")
576
676
  else:
@@ -19,6 +19,20 @@ paths:
19
19
  - **Config**: Access config via `config()` helper, never `env()` outside config files.
20
20
  - **Strict mode**: Models use strict mode (prevent lazy loading, silently discarding attributes, accessing missing attributes).
21
21
 
22
+ ## Laravel Boost MCP
23
+
24
+ Project MCP server auto-configured in `.mcp.json` by `/sk:laravel-init`. Provides 9 tools Claude can call directly:
25
+
26
+ | Tool | When to use |
27
+ |------|-------------|
28
+ | `DatabaseSchema` | Before writing migrations or queries — get exact column types, indexes, FKs |
29
+ | `DatabaseQuery` | Run read-only SELECTs to validate data assumptions |
30
+ | `SearchDocs` | Look up Laravel/Livewire/Filament/Pest docs matched to your installed versions |
31
+ | `ReadLogEntries` | Check recent errors without leaving Claude |
32
+ | `BrowserLogs` | Inspect browser console errors captured server-side |
33
+ | `LastError` | Get the last exception instantly |
34
+ | `ApplicationInfo` | Check installed packages and Eloquent models at session start |
35
+
22
36
  ## Code Refinement
23
37
 
24
38
  After running `/sk:execute-plan`, use the `laravel-simplifier` agent to refine recently modified PHP/Laravel code: