ima-claude 2.9.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.
- package/LICENSE +21 -0
- package/README.md +463 -0
- package/dist/cli.js +1064 -0
- package/package.json +49 -0
- package/platforms/claude/adapter.ts +115 -0
- package/platforms/junie/adapter.ts +254 -0
- package/platforms/junie/agents-template.md +113 -0
- package/platforms/junie/hook-translations.md +84 -0
- package/platforms/shared/detector.ts +27 -0
- package/platforms/shared/installer.ts +202 -0
- package/platforms/shared/types.ts +78 -0
- package/plugins/ima-claude/.claude-plugin/plugin.json +25 -0
- package/plugins/ima-claude/agents/explorer.md +30 -0
- package/plugins/ima-claude/agents/implementer.md +30 -0
- package/plugins/ima-claude/agents/memory.md +42 -0
- package/plugins/ima-claude/agents/reviewer.md +53 -0
- package/plugins/ima-claude/agents/tester.md +33 -0
- package/plugins/ima-claude/agents/wp-developer.md +46 -0
- package/plugins/ima-claude/hooks/README.md +145 -0
- package/plugins/ima-claude/hooks/atlassian_prereqs.py +112 -0
- package/plugins/ima-claude/hooks/block_sed_edits.py +59 -0
- package/plugins/ima-claude/hooks/bootstrap.sh +90 -0
- package/plugins/ima-claude/hooks/bootstrap_utility_check.py +94 -0
- package/plugins/ima-claude/hooks/composer_autoload_check.py +70 -0
- package/plugins/ima-claude/hooks/docs_organization.py +104 -0
- package/plugins/ima-claude/hooks/enforce_rg_over_grep.py +56 -0
- package/plugins/ima-claude/hooks/fp_utility_check.py +90 -0
- package/plugins/ima-claude/hooks/hook_logger.py +69 -0
- package/plugins/ima-claude/hooks/hooks.json +239 -0
- package/plugins/ima-claude/hooks/jira_issue_fetch.py +79 -0
- package/plugins/ima-claude/hooks/jquery_in_wordpress.py +92 -0
- package/plugins/ima-claude/hooks/memory_bootstrap.py +79 -0
- package/plugins/ima-claude/hooks/memory_store_reminder.py +75 -0
- package/plugins/ima-claude/hooks/prompt_coach.py +125 -0
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +48 -0
- package/plugins/ima-claude/hooks/prompt_coach_system.md +30 -0
- package/plugins/ima-claude/hooks/sequential_thinking_check.py +81 -0
- package/plugins/ima-claude/hooks/serena_over_grep.py +96 -0
- package/plugins/ima-claude/hooks/serena_over_read.py +66 -0
- package/plugins/ima-claude/hooks/serena_project_check.py +133 -0
- package/plugins/ima-claude/hooks/sql_injection_check.py +73 -0
- package/plugins/ima-claude/hooks/task_master_after_plan.py +31 -0
- package/plugins/ima-claude/hooks/task_master_before_impl.py +93 -0
- package/plugins/ima-claude/hooks/tavily_extract_advanced.py +48 -0
- package/plugins/ima-claude/hooks/vestige_before_external.py +86 -0
- package/plugins/ima-claude/hooks/webfetch_to_tavily.py +42 -0
- package/plugins/ima-claude/hooks/websearch_to_tavily.py +41 -0
- package/plugins/ima-claude/hooks/wp_security_check.py +150 -0
- package/plugins/ima-claude/personalities/README.md +45 -0
- package/plugins/ima-claude/personalities/enable-40k.md +69 -0
- package/plugins/ima-claude/personalities/enable-templars.md +69 -0
- package/plugins/ima-claude/skills/.research-summary.md +340 -0
- package/plugins/ima-claude/skills/architect/SKILL.md +304 -0
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +200 -0
- package/plugins/ima-claude/skills/discourse/SKILL.md +440 -0
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +192 -0
- package/plugins/ima-claude/skills/discourse-admin/references/api-endpoints.md +441 -0
- package/plugins/ima-claude/skills/discourse-admin/references/gotchas.md +107 -0
- package/plugins/ima-claude/skills/discourse-admin/references/staging-defaults.md +98 -0
- package/plugins/ima-claude/skills/discourse-admin/scripts/discourse-admin.py +319 -0
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +254 -0
- package/plugins/ima-claude/skills/docs-organize/templates/active-README.md +50 -0
- package/plugins/ima-claude/skills/docs-organize/templates/archive-README.md +57 -0
- package/plugins/ima-claude/skills/docs-organize/templates/docs-README.md +43 -0
- package/plugins/ima-claude/skills/docs-organize/templates/phase-archive-README.md +83 -0
- package/plugins/ima-claude/skills/docs-organize/templates/section-README.md +48 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-README.md +79 -0
- package/plugins/ima-claude/skills/docs-organize/templates/transient-gitignore +9 -0
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +496 -0
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +258 -0
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +278 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/bootstrap-patterns.md +356 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +273 -0
- package/plugins/ima-claude/skills/ima-bootstrap/references/theme-integration.md +212 -0
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +108 -0
- package/plugins/ima-claude/skills/ima-brand/references/brand-identity.md +140 -0
- package/plugins/ima-claude/skills/ima-brand/references/digital-standards.md +180 -0
- package/plugins/ima-claude/skills/ima-brand/references/visual-system.md +173 -0
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +175 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/container-components.md +154 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/examples.md +328 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/field-components.md +298 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/form-factory.md +193 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/quick-reference.md +153 -0
- package/plugins/ima-claude/skills/ima-forms-expert/references/validation-engine.md +336 -0
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +178 -0
- package/plugins/ima-claude/skills/jquery/SKILL.md +413 -0
- package/plugins/ima-claude/skills/js-fp/SKILL.md +463 -0
- package/plugins/ima-claude/skills/js-fp/core-principles.md +487 -0
- package/plugins/ima-claude/skills/js-fp/examples/pure-functions.js +260 -0
- package/plugins/ima-claude/skills/js-fp/examples/tests/pure-functions.test.js +262 -0
- package/plugins/ima-claude/skills/js-fp/references/anti-patterns.md +120 -0
- package/plugins/ima-claude/skills/js-fp/references/performance-patterns.md +116 -0
- package/plugins/ima-claude/skills/js-fp/references/testing-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +280 -0
- package/plugins/ima-claude/skills/js-fp-api/examples/crud-endpoint.js +258 -0
- package/plugins/ima-claude/skills/js-fp-api/references/middleware-patterns.md +134 -0
- package/plugins/ima-claude/skills/js-fp-api/references/security-sql.md +110 -0
- package/plugins/ima-claude/skills/js-fp-api/references/validation-patterns.md +165 -0
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +447 -0
- package/plugins/ima-claude/skills/js-fp-react/examples/ProductCard.tsx +65 -0
- package/plugins/ima-claude/skills/js-fp-react/references/hooks-advanced.md +136 -0
- package/plugins/ima-claude/skills/js-fp-react/references/performance-patterns.md +175 -0
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +322 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/complete-examples.md +397 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/composables-advanced.md +282 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/reactivity-patterns.md +348 -0
- package/plugins/ima-claude/skills/js-fp-vue/references/testing.md +314 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +301 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/ajax-patterns.md +192 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/event-patterns.md +136 -0
- package/plugins/ima-claude/skills/js-fp-wordpress/references/wp-integration.md +248 -0
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +209 -0
- package/plugins/ima-claude/skills/livecanvas/references/livecanvas-features.md +311 -0
- package/plugins/ima-claude/skills/livecanvas/references/loops-and-logic.md +730 -0
- package/plugins/ima-claude/skills/livecanvas/references/picostrap.md +227 -0
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +339 -0
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +109 -0
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +182 -0
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +233 -0
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +149 -0
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +174 -0
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +118 -0
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +259 -0
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +275 -0
- package/plugins/ima-claude/skills/php-authnet/references/api-reference.md +624 -0
- package/plugins/ima-claude/skills/php-authnet/references/sandbox-testing.md +424 -0
- package/plugins/ima-claude/skills/php-fp/SKILL.md +333 -0
- package/plugins/ima-claude/skills/php-fp/examples/pure-functions.php +403 -0
- package/plugins/ima-claude/skills/php-fp/examples/tests/PureFunctionsTest.php +515 -0
- package/plugins/ima-claude/skills/php-fp/references/core-principles.md +277 -0
- package/plugins/ima-claude/skills/php-fp/references/testing-patterns.md +374 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +216 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/fp-patterns.md +275 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/plugin-architecture.md +295 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/security-examples.md +203 -0
- package/plugins/ima-claude/skills/php-fp-wordpress/references/testing-strategy.md +259 -0
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +716 -0
- package/plugins/ima-claude/skills/playwright/SKILL.md +434 -0
- package/plugins/ima-claude/skills/playwright/references/accessibility-testing.md +153 -0
- package/plugins/ima-claude/skills/playwright/references/ci-cd.md +268 -0
- package/plugins/ima-claude/skills/playwright/references/network-mocking.md +270 -0
- package/plugins/ima-claude/skills/playwright/references/visual-regression.md +215 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +663 -0
- package/plugins/ima-claude/skills/py-fp/examples/pure-functions.py +185 -0
- package/plugins/ima-claude/skills/py-fp/examples/tests/test_pure_functions.py +244 -0
- package/plugins/ima-claude/skills/py-fp/references/core-principles.md +381 -0
- package/plugins/ima-claude/skills/py-fp/references/testing-patterns.md +283 -0
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +327 -0
- package/plugins/ima-claude/skills/quasar-fp/metadata.json +85 -0
- package/plugins/ima-claude/skills/quasar-fp/references/component-patterns.md +257 -0
- package/plugins/ima-claude/skills/quasar-fp/references/theme-integration.md +233 -0
- package/plugins/ima-claude/skills/quasar-fp/references/utility-classes.md +237 -0
- package/plugins/ima-claude/skills/quickstart/SKILL.md +129 -0
- package/plugins/ima-claude/skills/rails/SKILL.md +359 -0
- package/plugins/ima-claude/skills/resume-session/SKILL.md +68 -0
- package/plugins/ima-claude/skills/rg/SKILL.md +205 -0
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +336 -0
- package/plugins/ima-claude/skills/save-session/SKILL.md +81 -0
- package/plugins/ima-claude/skills/scorecard/SKILL.md +96 -0
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +127 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/advanced-checklist.md +44 -0
- package/plugins/ima-claude/skills/skill-analyzer/references/core-checklist.md +60 -0
- package/plugins/ima-claude/skills/skill-analyzer/scripts/analyze_skill.py +418 -0
- package/plugins/ima-claude/skills/skill-creator/LICENSE.txt +202 -0
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +343 -0
- package/plugins/ima-claude/skills/skill-creator/references/output-patterns.md +82 -0
- package/plugins/ima-claude/skills/skill-creator/references/workflows.md +28 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/ima-claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/plugins/ima-claude/skills/task-master/SKILL.md +51 -0
- package/plugins/ima-claude/skills/task-planner/SKILL.md +228 -0
- package/plugins/ima-claude/skills/task-runner/SKILL.md +192 -0
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +198 -0
- package/plugins/ima-claude/skills/unit-testing/references/mock-patterns.md +181 -0
- package/plugins/ima-claude/skills/unit-testing/references/tdd-workflow.md +177 -0
- package/plugins/ima-claude/skills/unit-testing/references/test-strategy.md +126 -0
- package/plugins/ima-claude/skills/wp-local/SKILL.md +246 -0
- package/plugins/ima-claude/skills/wp-local/references/configuration.md +198 -0
- package/plugins/ima-claude/skills/wp-local/references/wp-cli-reference.md +406 -0
- package/plugins/ima-claude/skills/wp-local/scripts/wp-local.sh +61 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "ruby-fp"
|
|
3
|
+
description: "Functional Ruby patterns - Enumerable as FP toolkit, lambdas, freeze, functional core/imperative shell"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Ruby FP
|
|
7
|
+
|
|
8
|
+
Ruby is OOP-first, but its FP toolkit is excellent. The goal is **functional core, imperative shell** — pure methods for logic, OOP shell only where the framework demands it.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Writing standalone Ruby scripts
|
|
13
|
+
- Building Ruby utilities or service objects
|
|
14
|
+
- Refactoring procedural Ruby toward composable units
|
|
15
|
+
- Any Ruby code where framework conventions don't dictate the pattern
|
|
16
|
+
|
|
17
|
+
## Core Philosophy
|
|
18
|
+
|
|
19
|
+
> Ruby's Enumerable is a functional toolkit hiding inside an OOP language.
|
|
20
|
+
|
|
21
|
+
The architect's lens applied to Ruby:
|
|
22
|
+
- **Pure methods** for logic (no instance variable mutation in calculation methods)
|
|
23
|
+
- **Enumerable over explicit loops** — `map/select/reduce` not `each` + accumulator
|
|
24
|
+
- **Lambdas** for first-class functions (strict arity, `lambda?` is true, `return` is scoped)
|
|
25
|
+
- **freeze** for value objects and constants
|
|
26
|
+
- **Functional core** isolated from I/O, database, external state
|
|
27
|
+
|
|
28
|
+
Ruby will never be Haskell. Don't fight the language — compose with it.
|
|
29
|
+
|
|
30
|
+
## Enumerable: The FP Toolkit
|
|
31
|
+
|
|
32
|
+
These are your primary tools. Prefer them over `each` + mutation.
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
users = [
|
|
36
|
+
{ name: 'Alice', age: 30, active: true },
|
|
37
|
+
{ name: 'Bob', age: 17, active: false },
|
|
38
|
+
{ name: 'Carol', age: 25, active: true }
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
# select — filter
|
|
42
|
+
adults = users.select { |u| u[:age] >= 18 }
|
|
43
|
+
|
|
44
|
+
# map — transform
|
|
45
|
+
names = users.map { |u| u[:name] }
|
|
46
|
+
|
|
47
|
+
# reduce — accumulate
|
|
48
|
+
total_age = users.reduce(0) { |sum, u| sum + u[:age] }
|
|
49
|
+
|
|
50
|
+
# filter_map — select + transform in one pass (Ruby 2.7+, preferred)
|
|
51
|
+
active_names = users.filter_map { |u| u[:name] if u[:active] }
|
|
52
|
+
|
|
53
|
+
# flat_map — map + flatten
|
|
54
|
+
tags = posts.flat_map { |p| p[:tags] }
|
|
55
|
+
|
|
56
|
+
# each_with_object — build a hash/array without external mutation
|
|
57
|
+
index = users.each_with_object({}) { |u, h| h[u[:name]] = u[:age] }
|
|
58
|
+
|
|
59
|
+
# group_by — partition
|
|
60
|
+
by_status = users.group_by { |u| u[:active] ? :active : :inactive }
|
|
61
|
+
|
|
62
|
+
# Chaining — functional pipeline
|
|
63
|
+
result = users
|
|
64
|
+
.select { |u| u[:active] }
|
|
65
|
+
.map { |u| u.merge(display_name: u[:name].upcase) }
|
|
66
|
+
.sort_by { |u| u[:age] }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Rule**: If you find yourself writing `results = []; collection.each { |x| results << x if ... }`, reach for `filter_map` instead.
|
|
70
|
+
|
|
71
|
+
## Lambdas vs Procs
|
|
72
|
+
|
|
73
|
+
Use `lambda` (or `->`) for reusable, composable functions. Avoid bare `proc` for logic units.
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# Lambda — strict arity, scoped return, first-class function
|
|
77
|
+
validate_age = ->(age) { age.is_a?(Integer) && age >= 0 && age <= 150 }
|
|
78
|
+
normalize_email = ->(email) { email.to_s.strip.downcase }
|
|
79
|
+
|
|
80
|
+
# Compose with >> (Ruby 2.6+)
|
|
81
|
+
process_user = normalize_email >> method(:save_user)
|
|
82
|
+
|
|
83
|
+
# Use as argument (higher-order functions)
|
|
84
|
+
def transform_all(items, transformer)
|
|
85
|
+
items.map(&transformer)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
transform_all(emails, normalize_email)
|
|
89
|
+
|
|
90
|
+
# Method references — convert instance/class methods to callables
|
|
91
|
+
validator = method(:validate_age)
|
|
92
|
+
emails.map(&method(:normalize_email))
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Lambda vs Proc differences that matter:**
|
|
96
|
+
| | Lambda | Proc |
|
|
97
|
+
|-|--------|------|
|
|
98
|
+
| Arity | Strict (raises ArgumentError) | Loose (fills nil) |
|
|
99
|
+
| `return` | Exits lambda only | Exits enclosing method |
|
|
100
|
+
| Use for | Reusable functions, composition | Blocks, iterators |
|
|
101
|
+
|
|
102
|
+
## Immutability with freeze
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# Freeze constants
|
|
106
|
+
VALID_STATUSES = %w[active inactive pending].freeze
|
|
107
|
+
DEFAULT_CONFIG = { timeout: 30, retries: 3 }.freeze
|
|
108
|
+
|
|
109
|
+
# Value object pattern — frozen struct
|
|
110
|
+
UserRecord = Data.define(:name, :email, :age) # Ruby 3.2+
|
|
111
|
+
user = UserRecord.new(name: 'Alice', email: 'alice@example.com', age: 30)
|
|
112
|
+
# user is immutable — no setters
|
|
113
|
+
|
|
114
|
+
# For older Ruby, use Struct with freeze
|
|
115
|
+
Config = Struct.new(:host, :port, :timeout).new('localhost', 5432, 30).freeze
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Rule**: Any hash/array used as a constant gets `.freeze`. Value objects use `Data.define` (Ruby 3.2+) or frozen `Struct`.
|
|
119
|
+
|
|
120
|
+
## Functional Core / Imperative Shell
|
|
121
|
+
|
|
122
|
+
The central pattern. Separate pure logic from I/O and external state.
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
# PURE CORE — no I/O, no DB, fully testable, no side effects
|
|
126
|
+
module UserLogic
|
|
127
|
+
def self.validate(attrs)
|
|
128
|
+
errors = []
|
|
129
|
+
errors << "Name required" if attrs[:name].to_s.strip.empty?
|
|
130
|
+
errors << "Invalid email" unless attrs[:email].to_s.include?('@')
|
|
131
|
+
errors << "Age must be 18+" if attrs[:age].to_i < 18
|
|
132
|
+
errors
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def self.normalize(attrs)
|
|
136
|
+
attrs.merge(
|
|
137
|
+
name: attrs[:name].to_s.strip,
|
|
138
|
+
email: attrs[:email].to_s.strip.downcase
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def self.prepare_for_save(raw_attrs)
|
|
143
|
+
normalized = normalize(raw_attrs)
|
|
144
|
+
errors = validate(normalized)
|
|
145
|
+
errors.empty? ? { ok: true, attrs: normalized } : { ok: false, errors: errors }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# IMPERATIVE SHELL — orchestrates I/O, calls pure core
|
|
150
|
+
def create_user(raw_params)
|
|
151
|
+
result = UserLogic.prepare_for_save(raw_params)
|
|
152
|
+
return { success: false, errors: result[:errors] } unless result[:ok]
|
|
153
|
+
|
|
154
|
+
user = User.create!(result[:attrs]) # database side effect here only
|
|
155
|
+
{ success: true, user: user }
|
|
156
|
+
end
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Pure Method Guidelines
|
|
160
|
+
|
|
161
|
+
A method is pure when:
|
|
162
|
+
1. Same inputs always return same output
|
|
163
|
+
2. No mutation of instance variables during computation
|
|
164
|
+
3. No I/O (logging, DB, network) inside the calculation
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
# BAD — mutates state during calculation
|
|
168
|
+
def calculate_totals
|
|
169
|
+
@subtotal = @items.sum { |i| i[:price] * i[:qty] }
|
|
170
|
+
@tax = @subtotal * 0.08
|
|
171
|
+
@total = @subtotal + @tax
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# GOOD — returns new values, no mutation
|
|
175
|
+
def self.calculate_totals(items, tax_rate: 0.08)
|
|
176
|
+
subtotal = items.sum { |i| i[:price] * i[:qty] }
|
|
177
|
+
tax = subtotal * tax_rate
|
|
178
|
+
{ subtotal: subtotal, tax: tax, total: subtotal + tax }
|
|
179
|
+
end
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Composition Patterns
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
# Method chaining on custom objects — return self or new instance
|
|
186
|
+
class Pipeline
|
|
187
|
+
def initialize(steps = [])
|
|
188
|
+
@steps = steps.freeze
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def add(step)
|
|
192
|
+
Pipeline.new(@steps + [step]) # returns new instance, immutable
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def call(input)
|
|
196
|
+
@steps.reduce(input) { |data, step| step.call(data) }
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Lambda composition with >>
|
|
201
|
+
sanitize = ->(s) { s.strip.downcase }
|
|
202
|
+
validate = ->(s) { raise "empty" if s.empty?; s }
|
|
203
|
+
normalize = sanitize >> validate
|
|
204
|
+
|
|
205
|
+
# Callable objects (duck-typed lambdas)
|
|
206
|
+
class Validator
|
|
207
|
+
def call(value)
|
|
208
|
+
value.is_a?(String) && !value.empty?
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
validators = [Validator.new, ->(v) { v.length < 255 }]
|
|
213
|
+
valid = validators.all? { |v| v.call(input) }
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Anti-Patterns to Avoid
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
# BAD — accumulator mutation inside each
|
|
220
|
+
result = []
|
|
221
|
+
items.each { |item| result << transform(item) if item[:active] }
|
|
222
|
+
# GOOD
|
|
223
|
+
result = items.filter_map { |item| transform(item) if item[:active] }
|
|
224
|
+
|
|
225
|
+
# BAD — output parameter mutation
|
|
226
|
+
def process(items, output)
|
|
227
|
+
items.each { |i| output << i * 2 }
|
|
228
|
+
end
|
|
229
|
+
# GOOD — return new value
|
|
230
|
+
def process(items)
|
|
231
|
+
items.map { |i| i * 2 }
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# BAD — complex logic inside a class with side effects mixed in
|
|
235
|
+
def calculate_and_save
|
|
236
|
+
total = @items.sum(&:price)
|
|
237
|
+
@total = total # side effect
|
|
238
|
+
DB.save(total) # side effect
|
|
239
|
+
total
|
|
240
|
+
end
|
|
241
|
+
# GOOD — separate concerns
|
|
242
|
+
total = calculate_total(@items) # pure
|
|
243
|
+
update_total(total) # side effect isolated
|
|
244
|
+
|
|
245
|
+
# BAD — bare proc for reusable function
|
|
246
|
+
adder = proc { |a, b| a + b } # loose arity, weird return behavior
|
|
247
|
+
# GOOD
|
|
248
|
+
adder = ->(a, b) { a + b }
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## When to Use Classes
|
|
252
|
+
|
|
253
|
+
OOP is fine for: stateful objects that model real entities (User, Order, Connection), framework integration (ActiveRecord models, controllers), objects that encapsulate a lifecycle.
|
|
254
|
+
|
|
255
|
+
Use modules with class methods (or plain lambdas/methods) for: pure logic, utilities, transformations, validators.
|
|
256
|
+
|
|
257
|
+
```ruby
|
|
258
|
+
# Module for pure logic — no instances needed
|
|
259
|
+
module PriceCalculator
|
|
260
|
+
def self.discount(price, tier)
|
|
261
|
+
rates = { bronze: 0.05, silver: 0.10, gold: 0.20 }.freeze
|
|
262
|
+
price * (1 - rates.fetch(tier, 0))
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Class for stateful lifecycle
|
|
267
|
+
class ImportJob
|
|
268
|
+
def initialize(source_db, config)
|
|
269
|
+
@source_db = source_db
|
|
270
|
+
@config = config
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def run
|
|
274
|
+
records = fetch_records # I/O
|
|
275
|
+
processed = process(records) # pure
|
|
276
|
+
persist(processed) # I/O
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
private
|
|
280
|
+
|
|
281
|
+
def process(records)
|
|
282
|
+
records
|
|
283
|
+
.select { |r| valid?(r) }
|
|
284
|
+
.map { |r| transform(r) }
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Security Notes for Standalone Scripts
|
|
290
|
+
|
|
291
|
+
- **Never interpolate external input into shell commands** — use `Open3.capture3` with array args, not `system("cmd #{input}")`
|
|
292
|
+
- **Never interpolate input into SQL** — use parameterized queries or the driver's escape method
|
|
293
|
+
- **ENV for credentials** — never hardcode; raise if missing: `ENV.fetch('DB_PASSWORD')`
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
# BAD — shell injection
|
|
297
|
+
system("convert #{filename} output.png")
|
|
298
|
+
|
|
299
|
+
# GOOD — array form, no shell expansion
|
|
300
|
+
require 'open3'
|
|
301
|
+
stdout, stderr, status = Open3.capture3('convert', filename, 'output.png')
|
|
302
|
+
|
|
303
|
+
# BAD — hardcoded credential
|
|
304
|
+
client = Mysql2::Client.new(password: 'secret123')
|
|
305
|
+
|
|
306
|
+
# GOOD — fail loudly if not set
|
|
307
|
+
client = Mysql2::Client.new(password: ENV.fetch('MYSQL_PASSWORD'))
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Quick Reference: When to Reach for What
|
|
311
|
+
|
|
312
|
+
| Need | Use |
|
|
313
|
+
|------|-----|
|
|
314
|
+
| Transform a collection | `map` |
|
|
315
|
+
| Filter a collection | `select` / `reject` |
|
|
316
|
+
| Transform + filter in one pass | `filter_map` |
|
|
317
|
+
| Accumulate to a single value | `reduce` / `inject` |
|
|
318
|
+
| Build a hash from a collection | `each_with_object` / `to_h` |
|
|
319
|
+
| Group by a property | `group_by` |
|
|
320
|
+
| Reusable function | `lambda` / `->` |
|
|
321
|
+
| Compose functions | `>>` operator |
|
|
322
|
+
| Immutable constant | `.freeze` |
|
|
323
|
+
| Immutable value object | `Data.define` (Ruby 3.2+) or frozen `Struct` |
|
|
324
|
+
| Pure logic module | `module Foo; def self.method...` |
|
|
325
|
+
|
|
326
|
+
## When to Load Reference Files
|
|
327
|
+
|
|
328
|
+
### FP Patterns Deep Dive
|
|
329
|
+
**File**: [`references/patterns.md`](references/patterns.md)
|
|
330
|
+
**Load when**: Need advanced composition, lazy enumerables, currying, memoization
|
|
331
|
+
**Contains**: Lazy evaluation, `Comparable`/`Enumerable` mixin, memoization patterns, full pipeline example
|
|
332
|
+
|
|
333
|
+
### Security Examples
|
|
334
|
+
**File**: [`references/security.md`](references/security.md)
|
|
335
|
+
**Load when**: Working with external input, SQL, shell commands, file operations
|
|
336
|
+
**Contains**: SQL parameterization, shell safety, input validation, ENV credential management
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "save-session"
|
|
3
|
+
description: "Save session state to Serena MCP memory (no file path confusion)"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# save-session
|
|
7
|
+
|
|
8
|
+
Save current session state to Serena MCP memory for cross-session persistence.
|
|
9
|
+
|
|
10
|
+
## Trigger Phrases
|
|
11
|
+
|
|
12
|
+
- "save session"
|
|
13
|
+
- "save the session"
|
|
14
|
+
- "save current session"
|
|
15
|
+
- "create session save"
|
|
16
|
+
- "checkpoint session"
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
Use `mcp__serena__write_memory` to save session state.
|
|
21
|
+
|
|
22
|
+
**Memory name**: `session-state`
|
|
23
|
+
|
|
24
|
+
**Content format**:
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
# Session State
|
|
28
|
+
Saved: {current_date_time}
|
|
29
|
+
|
|
30
|
+
## Current Task
|
|
31
|
+
{1-2 sentences describing the active task or goal}
|
|
32
|
+
|
|
33
|
+
## Modified Files
|
|
34
|
+
- {path/to/file1}
|
|
35
|
+
- {path/to/file2}
|
|
36
|
+
|
|
37
|
+
## Decisions Made
|
|
38
|
+
- {Key decision 1}
|
|
39
|
+
- {Key decision 2}
|
|
40
|
+
|
|
41
|
+
## Technical Context
|
|
42
|
+
- **Relevant code**: {endpoints, functions, components involved}
|
|
43
|
+
- **Patterns**: {FP patterns, type constraints, architectural decisions}
|
|
44
|
+
- **Dependencies**: {external libraries, services, APIs}
|
|
45
|
+
|
|
46
|
+
## Outstanding Items
|
|
47
|
+
- [ ] {Incomplete item or next step}
|
|
48
|
+
- [ ] {Blocker or open question}
|
|
49
|
+
|
|
50
|
+
## Resume Hint
|
|
51
|
+
{One sentence: what to do first when resuming}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Rules
|
|
55
|
+
|
|
56
|
+
**Include:**
|
|
57
|
+
- Active task state (what's in progress)
|
|
58
|
+
- Files touched this session
|
|
59
|
+
- Decisions that affect future work
|
|
60
|
+
- Blockers or open questions
|
|
61
|
+
- Enough context to resume without re-reading entire codebase
|
|
62
|
+
|
|
63
|
+
**Exclude:**
|
|
64
|
+
- Conversation history or dialogue
|
|
65
|
+
- Code snippets (the actual files have the code)
|
|
66
|
+
- Completed work that doesn't affect next steps
|
|
67
|
+
- Research paths that led nowhere
|
|
68
|
+
- Obvious context (project name, basic structure)
|
|
69
|
+
|
|
70
|
+
## After Writing
|
|
71
|
+
|
|
72
|
+
Confirm with: "Session saved to Serena memory 'session-state'"
|
|
73
|
+
|
|
74
|
+
**Note:** For persistent knowledge (decisions, patterns, preferences) that should survive beyond this session, use Vestige via `smart_ingest` — not Serena memory. Serena is for ephemeral session state only.
|
|
75
|
+
|
|
76
|
+
## Technical Notes
|
|
77
|
+
|
|
78
|
+
- Uses Serena MCP `write_memory` tool (no file path confusion)
|
|
79
|
+
- Memory persists across Claude sessions in project context
|
|
80
|
+
- Overwrites previous session-state (single checkpoint model)
|
|
81
|
+
- Project-specific storage (appropriate for session state)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scorecard
|
|
3
|
+
description: "Generate a quick visual scorecard for any project's README. Scores codebase on Code Standards, Security, Test Coverage, Documentation, and Maintainability using a Markdown table with letter grades and color indicators. Use when: user wants a project review with scores, project quality assessment, README badge/scorecard generation, or code health check. Usage: /scorecard [skill1] [skill2] ... where skills are the domain-relevant FP/framework skills to evaluate against (e.g., js-fp js-fp-api, or php-fp php-fp-wordpress)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scorecard — Project Quality Assessment
|
|
7
|
+
|
|
8
|
+
Generate a compact visual scorecard and insert it into the project README.
|
|
9
|
+
|
|
10
|
+
## Invocation
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
/scorecard js-fp js-fp-api
|
|
14
|
+
/scorecard php-fp php-fp-wordpress
|
|
15
|
+
/scorecard js-fp js-fp-vue quasar-fp
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Arguments are domain skills to evaluate against. If none provided, auto-detect from project files.
|
|
19
|
+
|
|
20
|
+
## Process
|
|
21
|
+
|
|
22
|
+
Use `task-master` to organize all work. Delegate review categories to parallel agents.
|
|
23
|
+
|
|
24
|
+
### Step 1: Setup
|
|
25
|
+
|
|
26
|
+
1. Invoke `task-master` skill for orchestration
|
|
27
|
+
2. Invoke each domain skill passed as arguments (these define the code standards to score against)
|
|
28
|
+
3. Identify the project's primary language(s) and framework(s)
|
|
29
|
+
4. Locate the README (or note its absence)
|
|
30
|
+
|
|
31
|
+
### Step 2: Parallel Review (delegate via task-master)
|
|
32
|
+
|
|
33
|
+
Spawn parallel agents for each scoring category:
|
|
34
|
+
|
|
35
|
+
| Category | What to Evaluate | Key Signals |
|
|
36
|
+
|----------|-----------------|-------------|
|
|
37
|
+
| **Code Standards** | FP adherence, naming, patterns, consistency | Pure functions, immutability, composition, no anti-patterns from loaded skills |
|
|
38
|
+
| **Security** | Input validation, injection risks, auth patterns, secrets | OWASP top 10, hardcoded credentials, SQL/XSS/command injection, dependency vulnerabilities |
|
|
39
|
+
| **Test Coverage** | Test existence, quality, edge cases | Test files present, assertions meaningful, critical paths covered |
|
|
40
|
+
| **Documentation** | README quality, inline docs where needed, API docs | Setup instructions, usage examples, architecture notes |
|
|
41
|
+
| **Maintainability** | Complexity, coupling, file organization, dead code | Small functions, clear boundaries, no circular deps, sensible structure |
|
|
42
|
+
|
|
43
|
+
Each agent should:
|
|
44
|
+
- Use `model: "sonnet"` (Opus orchestrates, Sonnet evaluates)
|
|
45
|
+
- Scan relevant files for its category
|
|
46
|
+
- Return a letter grade (A-F) with 2-3 bullet points justifying the score
|
|
47
|
+
- Be honest — inflated scores help nobody
|
|
48
|
+
|
|
49
|
+
### Step 3: Compile Scores
|
|
50
|
+
|
|
51
|
+
Collect agent results into the scorecard table format:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Scorecard
|
|
55
|
+
|
|
56
|
+
| Category | Grade | Notes |
|
|
57
|
+
|----------|-------|-------|
|
|
58
|
+
| Code Standards | 🟢 A | Brief justification |
|
|
59
|
+
| Security | 🟡 B | Brief justification |
|
|
60
|
+
| Test Coverage | 🔴 D | Brief justification |
|
|
61
|
+
| Documentation | 🟡 C | Brief justification |
|
|
62
|
+
| Maintainability | 🟢 A | Brief justification |
|
|
63
|
+
|
|
64
|
+
> Last reviewed: YYYY-MM-DD · Skills: js-fp, js-fp-api
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Grading Scale
|
|
68
|
+
|
|
69
|
+
**Formatting rules (non-negotiable):**
|
|
70
|
+
- Use **exact emoji characters**: `🟢` `🟡` `🔴` — never GitHub shortcodes (`:green_circle:`), never Unicode geometric shapes (`●`, `◐`, `○`). Shortcodes don't render outside GitHub; geometric shapes are grey in terminals.
|
|
71
|
+
- Use **whole letter grades only**: A, B, C, D, F — no `+` or `-` modifiers. Nuance belongs in the Notes column, not the grade.
|
|
72
|
+
- Format as `🟢 A` (emoji + space + letter) — no backticks around the grade in the README output.
|
|
73
|
+
|
|
74
|
+
| Grade | Indicator | Meaning |
|
|
75
|
+
|-------|-----------|---------|
|
|
76
|
+
| A | 🟢 A | Excellent — meets or exceeds standards |
|
|
77
|
+
| B | 🟢 B | Good — minor improvements possible |
|
|
78
|
+
| C | 🟡 C | Adequate — notable gaps to address |
|
|
79
|
+
| D | 🔴 D | Poor — significant issues |
|
|
80
|
+
| F | 🔴 F | Failing — critical problems |
|
|
81
|
+
|
|
82
|
+
### Step 4: Insert into README
|
|
83
|
+
|
|
84
|
+
- Find the existing `## Scorecard` section and replace it, OR
|
|
85
|
+
- Insert after the first heading (title) if no scorecard section exists
|
|
86
|
+
- Keep the table compact — no lengthy explanations in the README
|
|
87
|
+
- Present the full scorecard to the user before writing, in case they want adjustments
|
|
88
|
+
|
|
89
|
+
## Guidelines
|
|
90
|
+
|
|
91
|
+
- **Honest scores only.** A scorecard that says everything is an A is useless.
|
|
92
|
+
- **Notes are terse.** Each note is 5-10 words max. The scorecard is a glance, not a report.
|
|
93
|
+
- **Domain skills define "Code Standards."** The loaded FP/framework skills set the bar for what good looks like.
|
|
94
|
+
- **Security is always evaluated** regardless of which domain skills are passed.
|
|
95
|
+
- **Auto-detect when no skills given.** Scan for package.json (JS), composer.json (PHP), etc. and suggest appropriate skills.
|
|
96
|
+
- **Date stamp every scorecard** so readers know how fresh it is.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-analyzer
|
|
3
|
+
description: Analyzes Skills against best practices and provides actionable improvement recommendations. Use when reviewing, auditing, or improving existing Skills (.skill files or skill directories), when validating Skills before distribution, or when the user asks for feedback on a skill they're developing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill Analyzer
|
|
7
|
+
|
|
8
|
+
Evaluate Skills against documented best practices and provide actionable feedback.
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
1. Run automated validation:
|
|
13
|
+
```bash
|
|
14
|
+
python scripts/analyze_skill.py /path/to/skill-directory
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. Review the analysis report for issues and recommendations
|
|
18
|
+
|
|
19
|
+
3. For manual deep-dive, follow the Analysis Workflow below
|
|
20
|
+
|
|
21
|
+
## Analysis Workflow
|
|
22
|
+
|
|
23
|
+
### Phase 1: Structural Validation
|
|
24
|
+
|
|
25
|
+
Check YAML frontmatter requirements:
|
|
26
|
+
- `name`: Present, ≤64 chars, lowercase letters/numbers/hyphens only, no reserved words (anthropic, claude)
|
|
27
|
+
- `description`: Present, non-empty, ≤1024 chars, no XML tags
|
|
28
|
+
|
|
29
|
+
Check file organization:
|
|
30
|
+
- SKILL.md exists at root
|
|
31
|
+
- Body ≤500 lines (optimal context efficiency)
|
|
32
|
+
- References are one level deep from SKILL.md (no nested chains)
|
|
33
|
+
|
|
34
|
+
### Phase 2: Description Quality
|
|
35
|
+
|
|
36
|
+
**Good descriptions include:**
|
|
37
|
+
- What the skill does
|
|
38
|
+
- When/triggers for using it
|
|
39
|
+
- Key terms users might mention
|
|
40
|
+
|
|
41
|
+
**Red flags:**
|
|
42
|
+
- Vague: "helps with documents", "processes data"
|
|
43
|
+
- First/second person: "I can help you...", "You can use this to..."
|
|
44
|
+
- Missing trigger contexts
|
|
45
|
+
|
|
46
|
+
**Example transformation:**
|
|
47
|
+
```
|
|
48
|
+
Bad: "Helps with PDFs"
|
|
49
|
+
Good: "Extracts text and tables from PDF files, fills forms, merges documents.
|
|
50
|
+
Use when working with PDF files or when the user mentions PDFs, forms,
|
|
51
|
+
or document extraction."
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Phase 3: Content Efficiency
|
|
55
|
+
|
|
56
|
+
**Check for over-explanation:**
|
|
57
|
+
- Does the skill explain concepts Claude already knows?
|
|
58
|
+
- Are there verbose paragraphs that could be concise code examples?
|
|
59
|
+
- Token cost vs. value delivered?
|
|
60
|
+
|
|
61
|
+
**Conciseness test:** For each section ask:
|
|
62
|
+
1. "Does Claude really need this?"
|
|
63
|
+
2. "Can I assume Claude knows this?"
|
|
64
|
+
3. "Does this justify its token cost?"
|
|
65
|
+
|
|
66
|
+
### Phase 4: Progressive Disclosure
|
|
67
|
+
|
|
68
|
+
**Verify proper layering:**
|
|
69
|
+
1. Metadata (name + description) - triggers skill selection
|
|
70
|
+
2. SKILL.md body - core instructions loaded on trigger
|
|
71
|
+
3. Reference files - loaded only when needed
|
|
72
|
+
|
|
73
|
+
**Check reference patterns:**
|
|
74
|
+
- Large content (>100 lines) split into separate files
|
|
75
|
+
- Reference files have table of contents if >100 lines
|
|
76
|
+
- Domain-specific content organized by domain
|
|
77
|
+
- Clear pointers in SKILL.md to when each reference should be read
|
|
78
|
+
|
|
79
|
+
### Phase 5: Workflow Quality
|
|
80
|
+
|
|
81
|
+
For skills with multi-step processes:
|
|
82
|
+
- Steps are clear and sequential
|
|
83
|
+
- Decision points have conditional guidance
|
|
84
|
+
- Feedback loops exist for quality-critical operations
|
|
85
|
+
- Validation steps precede irreversible actions
|
|
86
|
+
|
|
87
|
+
### Phase 6: Anti-Pattern Detection
|
|
88
|
+
|
|
89
|
+
Check for these common issues:
|
|
90
|
+
|
|
91
|
+
| Anti-Pattern | Detection | Fix |
|
|
92
|
+
|--------------|-----------|-----|
|
|
93
|
+
| Too many options | Multiple equivalent approaches offered | Provide one default + escape hatch |
|
|
94
|
+
| Windows paths | Backslashes in file paths | Use forward slashes everywhere |
|
|
95
|
+
| Time-sensitive info | Dates, "before/after X" conditionals | Use "old patterns" section or remove |
|
|
96
|
+
| Inconsistent terminology | Same concept, multiple terms | Choose one term throughout |
|
|
97
|
+
| Deeply nested refs | File A → File B → File C | Flatten to one level from SKILL.md |
|
|
98
|
+
| Voodoo constants | Unexplained magic numbers in scripts | Document why each value was chosen |
|
|
99
|
+
| Excessive files | README, CHANGELOG, QUICK_REFERENCE | Only SKILL.md + essential resources |
|
|
100
|
+
|
|
101
|
+
## Output Report Format
|
|
102
|
+
|
|
103
|
+
After analysis, produce a structured report:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
# Skill Analysis: [skill-name]
|
|
107
|
+
|
|
108
|
+
## Summary
|
|
109
|
+
- Overall assessment: [Pass/Needs Work/Major Issues]
|
|
110
|
+
- Lines: X (target: <500)
|
|
111
|
+
- Description quality: [Good/Needs Work]
|
|
112
|
+
|
|
113
|
+
## Critical Issues
|
|
114
|
+
[Issues that must be fixed]
|
|
115
|
+
|
|
116
|
+
## Recommendations
|
|
117
|
+
[Improvements that would help but aren't blocking]
|
|
118
|
+
|
|
119
|
+
## Strengths
|
|
120
|
+
[What the skill does well]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Detailed Checklists
|
|
124
|
+
|
|
125
|
+
For comprehensive evaluation criteria, see:
|
|
126
|
+
- [references/core-checklist.md](references/core-checklist.md) - Essential quality checks
|
|
127
|
+
- [references/advanced-checklist.md](references/advanced-checklist.md) - For skills with scripts/code
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Advanced Checklist (Skills with Scripts)
|
|
2
|
+
|
|
3
|
+
Use in addition to core-checklist.md when analyzing Skills that include executable code.
|
|
4
|
+
|
|
5
|
+
## Script Quality
|
|
6
|
+
|
|
7
|
+
- [ ] Scripts solve problems rather than punt to Claude
|
|
8
|
+
- [ ] Error handling is explicit and helpful
|
|
9
|
+
- [ ] No "voodoo constants" (all values justified and documented)
|
|
10
|
+
- [ ] Scripts are self-documenting with clear comments
|
|
11
|
+
- [ ] Clear distinction between "execute" vs "read as reference"
|
|
12
|
+
|
|
13
|
+
## Dependencies
|
|
14
|
+
|
|
15
|
+
- [ ] Required packages listed in instructions
|
|
16
|
+
- [ ] Packages verified as available in target environment
|
|
17
|
+
- [ ] Version constraints specified where necessary
|
|
18
|
+
- [ ] Installation commands provided
|
|
19
|
+
|
|
20
|
+
## Verification & Feedback Loops
|
|
21
|
+
|
|
22
|
+
- [ ] Validation steps for critical operations
|
|
23
|
+
- [ ] Feedback loops for quality-critical tasks
|
|
24
|
+
- [ ] Intermediate outputs are machine-verifiable
|
|
25
|
+
- [ ] Error messages are specific and actionable
|
|
26
|
+
|
|
27
|
+
## File Path Conventions
|
|
28
|
+
|
|
29
|
+
- [ ] All paths use forward slashes (Unix-style)
|
|
30
|
+
- [ ] Relative paths used where possible
|
|
31
|
+
- [ ] Path references are correct and exist
|
|
32
|
+
|
|
33
|
+
## Script Documentation
|
|
34
|
+
|
|
35
|
+
- [ ] Clear usage examples in SKILL.md
|
|
36
|
+
- [ ] Expected input/output documented
|
|
37
|
+
- [ ] Error conditions documented
|
|
38
|
+
- [ ] Return codes/exit statuses explained where relevant
|
|
39
|
+
|
|
40
|
+
## MCP Tool References (if applicable)
|
|
41
|
+
|
|
42
|
+
- [ ] Fully qualified tool names used (ServerName:tool_name)
|
|
43
|
+
- [ ] Server names match available MCP servers
|
|
44
|
+
- [ ] Tool capabilities accurately described
|