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,178 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jira-checkpoint
|
|
3
|
+
description: >-
|
|
4
|
+
Jira awareness checkpoints for team visibility around development work.
|
|
5
|
+
Lightweight companion to task-master — adds before/during/after Jira sync
|
|
6
|
+
without modifying execution workflow. Use when: "let's work on", "implement",
|
|
7
|
+
"build", "fix", "finished", "completed", "done with", "FNR-", "Jira story",
|
|
8
|
+
planning discussions about features or fixes, or when referencing Jira issue keys.
|
|
9
|
+
Triggers on: FNR-, Jira, story, sprint work, significant feature/fix starts,
|
|
10
|
+
work completion signals.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Jira Checkpoint - Team Visibility Layer
|
|
14
|
+
|
|
15
|
+
**"Work gets done. Does the team know?"**
|
|
16
|
+
|
|
17
|
+
Claude Code makes us 3-5x faster. Jira becomes the bottleneck — not the work, but remembering to update it. This skill adds lightweight checkpoints so team visibility stays current without breaking flow.
|
|
18
|
+
|
|
19
|
+
## Responsibility Separation
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
task-master = "How do I organize my work?" (execution, tactical)
|
|
23
|
+
jira-checkpoint = "Does the team know?" (visibility, strategic)
|
|
24
|
+
mcp-atlassian = "How do I talk to Jira's API?" (implementation, reference)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**No overlap.** task-master owns TaskList, decomposition, and delegation. jira-checkpoint owns the question "should we sync with Jira?" mcp-atlassian owns the API mechanics. Each skill stays in its lane.
|
|
28
|
+
|
|
29
|
+
## The Three Checkpoints
|
|
30
|
+
|
|
31
|
+
### 1. Before Work (Planning)
|
|
32
|
+
|
|
33
|
+
**When:** User starts significant work — "let's implement", "build the", "fix the", "work on FNR-".
|
|
34
|
+
|
|
35
|
+
**Action:** Ask one question:
|
|
36
|
+
|
|
37
|
+
> "Should I search Jira (FNR project) for related stories before we start?"
|
|
38
|
+
|
|
39
|
+
**Decision tree:**
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Is this significant work (feature, fix, refactor)?
|
|
43
|
+
├── YES → Ask about Jira search
|
|
44
|
+
│ User says yes → searchJiraIssuesUsingJql with FNR project
|
|
45
|
+
│ User says skip → Proceed, no Jira
|
|
46
|
+
└── NO (trivial utility, config tweak, typo fix) → Stay silent
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**What counts as "significant":**
|
|
50
|
+
- New feature or component
|
|
51
|
+
- Bug fix with user impact
|
|
52
|
+
- Refactor touching multiple files
|
|
53
|
+
- Anything that would reasonably be a Jira story
|
|
54
|
+
|
|
55
|
+
**What stays silent:**
|
|
56
|
+
- Adding a utility function
|
|
57
|
+
- Config file tweaks
|
|
58
|
+
- Formatting/linting fixes
|
|
59
|
+
- Internal refactors with no external impact
|
|
60
|
+
|
|
61
|
+
### 2. During Work (Context)
|
|
62
|
+
|
|
63
|
+
**When:** User references a Jira issue key (e.g., `FNR-123`).
|
|
64
|
+
|
|
65
|
+
**Action:** Auto-fetch the issue details and surface relevant context:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Detected FNR-123. Fetching story context...
|
|
69
|
+
|
|
70
|
+
→ "As a user, I want to reset my password via email"
|
|
71
|
+
→ Acceptance criteria: [list]
|
|
72
|
+
→ Status: In Progress | Assignee: Eric
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Implementation:** Use `getJiraIssue` with fields: `summary,description,status,assignee,customfield_10016` (acceptance criteria). See mcp-atlassian skill for field filtering patterns.
|
|
76
|
+
|
|
77
|
+
**Decision tree:**
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Did user mention an issue key (FNR-NNN)?
|
|
81
|
+
├── YES → Auto-fetch, surface summary + acceptance criteria
|
|
82
|
+
│ Already fetched this session? → Skip (don't re-fetch)
|
|
83
|
+
└── NO → Stay silent
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. After Work (Sync)
|
|
87
|
+
|
|
88
|
+
**When:** Work completes and a Jira story was referenced or discovered during the session.
|
|
89
|
+
|
|
90
|
+
**Action:** Ask one question:
|
|
91
|
+
|
|
92
|
+
> "We referenced FNR-123 during this work. Want to update its status or add a progress comment?"
|
|
93
|
+
|
|
94
|
+
**Decision tree:**
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Is work wrapping up AND was a Jira story involved?
|
|
98
|
+
├── YES → Ask about status update / comment
|
|
99
|
+
│ User says yes → Use transitionJiraIssue or addCommentToJiraIssue
|
|
100
|
+
│ User says skip → Done, no update
|
|
101
|
+
└── NO story involved → Stay silent
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**What "wrapping up" looks like:**
|
|
105
|
+
- User says "done", "finished", "that's it", "ship it"
|
|
106
|
+
- Commit created for the feature/fix
|
|
107
|
+
- PR created or ready
|
|
108
|
+
|
|
109
|
+
## Integration Points
|
|
110
|
+
|
|
111
|
+
### mcp-atlassian (API Reference)
|
|
112
|
+
|
|
113
|
+
All Jira operations use tools from mcp-atlassian. Do NOT duplicate API docs here — refer to that skill for:
|
|
114
|
+
- Tool catalog and parameters
|
|
115
|
+
- Token-saving field filtering
|
|
116
|
+
- JQL query patterns
|
|
117
|
+
- Comment and transition workflows
|
|
118
|
+
|
|
119
|
+
**Key tools used by checkpoints:**
|
|
120
|
+
- `searchJiraIssuesUsingJql` — Before Work search
|
|
121
|
+
- `getJiraIssue` — During Work context fetch
|
|
122
|
+
- `transitionJiraIssue` — After Work status update
|
|
123
|
+
- `addCommentToJiraIssue` — After Work progress comment
|
|
124
|
+
- `getAccessibleAtlassianResources` — Required bootstrap (cloudId)
|
|
125
|
+
|
|
126
|
+
### task-master (No Overlap)
|
|
127
|
+
|
|
128
|
+
task-master manages TaskList items and work decomposition. jira-checkpoint never:
|
|
129
|
+
- Creates or modifies TaskList items
|
|
130
|
+
- Changes task decomposition strategy
|
|
131
|
+
- Interferes with delegation patterns
|
|
132
|
+
|
|
133
|
+
They complement: task-master breaks work down, jira-checkpoint ensures Jira reflects it.
|
|
134
|
+
|
|
135
|
+
### Vestige (Learning Preferences)
|
|
136
|
+
|
|
137
|
+
Store user checkpoint preferences via Vestige:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
User says "skip Jira" repeatedly → smart_ingest preference: "User prefers minimal Jira checkpoints"
|
|
141
|
+
User always updates after work → smart_ingest preference: "User wants post-work Jira sync prompts"
|
|
142
|
+
User never wants before-work → smart_ingest preference: "Skip before-work Jira checkpoint"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Check Vestige at session start for stored Jira checkpoint preferences.
|
|
146
|
+
|
|
147
|
+
## User Control
|
|
148
|
+
|
|
149
|
+
**Every checkpoint is a question, never a mandate.**
|
|
150
|
+
|
|
151
|
+
- User can always say "skip Jira", "not now", "no Jira today"
|
|
152
|
+
- Preferences accumulate in Vestige — skill adapts over time
|
|
153
|
+
- No checkpoint ever blocks work from proceeding
|
|
154
|
+
- If user seems annoyed by prompts, reduce frequency and store preference
|
|
155
|
+
|
|
156
|
+
## Project Configuration
|
|
157
|
+
|
|
158
|
+
**Default project key:** `FNR`
|
|
159
|
+
|
|
160
|
+
When searching Jira without a specific issue key, scope to the FNR project:
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
JQL: project = FNR AND summary ~ "keyword" ORDER BY updated DESC
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Experimental Status
|
|
167
|
+
|
|
168
|
+
This skill is built for vetting. Expected evolution:
|
|
169
|
+
|
|
170
|
+
1. **v1 (now):** Three manual checkpoints with questions
|
|
171
|
+
2. **v2 (after feedback):** Adjusted trigger sensitivity based on usage patterns
|
|
172
|
+
3. **v3 (if valuable):** Deeper task-master integration (auto-suggest Jira links for TaskList items)
|
|
173
|
+
|
|
174
|
+
**Feedback signals to watch:**
|
|
175
|
+
- How often does the user accept vs skip checkpoints?
|
|
176
|
+
- Are before-work searches actually useful?
|
|
177
|
+
- Does after-work sync feel natural or forced?
|
|
178
|
+
- Is the FNR project scope too narrow?
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jquery
|
|
3
|
+
description: >-
|
|
4
|
+
jQuery patterns and API reference for WordPress/Bootstrap environments where jQuery
|
|
5
|
+
is already loaded. FP-aligned: chaining as composition, $.map/$.grep as declarative
|
|
6
|
+
transforms, pure logic extraction. Use when: writing DOM manipulation in WordPress
|
|
7
|
+
themes/plugins, working with Bootstrap JS components, handling events on dynamic
|
|
8
|
+
content, AJAX in WordPress, any browser JS where jQuery is available. Triggers on:
|
|
9
|
+
jQuery, $(), .on(), .find(), .ajax(), $.each, DOM manipulation in WordPress context,
|
|
10
|
+
Bootstrap JS, "how do I select", "how do I toggle", event delegation, IIFE wrapper.
|
|
11
|
+
IMPORTANT: In WordPress, jQuery IS native (0 additional bytes). Default to jQuery
|
|
12
|
+
for DOM work unless building an isolated module with no WP plugin interaction.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# jQuery - FP-Aligned Patterns
|
|
16
|
+
|
|
17
|
+
**"jQuery IS native in WordPress. Reach for it first."**
|
|
18
|
+
|
|
19
|
+
## Why This Skill Exists
|
|
20
|
+
|
|
21
|
+
Agents default to verbose vanilla JS even when jQuery is loaded and simpler. In WordPress, jQuery is **always available** (core dependency, 0 additional bytes). Writing `document.querySelectorAll('.foo').forEach(el => el.addEventListener('click', ...))` when `$('.foo').on('click', ...)` exists is unnecessary complexity.
|
|
22
|
+
|
|
23
|
+
**This skill ensures jQuery is the default for DOM work in WordPress/Bootstrap environments.**
|
|
24
|
+
|
|
25
|
+
## When to Use jQuery (Decision Tree)
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Writing browser JS in a WordPress environment?
|
|
29
|
+
├── YES: Does it touch the DOM (select, manipulate, events, AJAX)?
|
|
30
|
+
│ ├── YES → Use jQuery (default choice)
|
|
31
|
+
│ │ Exception: Pure business logic (calculations, validation, formatting)
|
|
32
|
+
│ │ → Keep as vanilla JS in pure/ directory (testable without DOM)
|
|
33
|
+
│ └── NO (pure data transforms, utilities) → Vanilla JS
|
|
34
|
+
├── Is jQuery already loaded on the page?
|
|
35
|
+
│ ├── YES → Use jQuery for DOM work
|
|
36
|
+
│ └── NO → Vanilla JS (don't add jQuery just for convenience)
|
|
37
|
+
└── NO WordPress context?
|
|
38
|
+
└── See js-fp for vanilla patterns
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Strong signals to use jQuery:**
|
|
42
|
+
- WordPress theme or plugin JavaScript
|
|
43
|
+
- Bootstrap component initialization or interaction
|
|
44
|
+
- Gravity Forms, ACF, or any jQuery-based plugin integration
|
|
45
|
+
- AJAX calls to `admin-ajax.php` or WP REST API
|
|
46
|
+
- Event delegation on dynamic content
|
|
47
|
+
- DOM traversal and manipulation
|
|
48
|
+
|
|
49
|
+
**Signals to use vanilla JS instead:**
|
|
50
|
+
- Pure business logic (no DOM)
|
|
51
|
+
- Isolated ES module with no WP plugin interaction
|
|
52
|
+
- Node.js / server-side code
|
|
53
|
+
- React/Vue component internals
|
|
54
|
+
|
|
55
|
+
## jQuery + FP: They're Compatible
|
|
56
|
+
|
|
57
|
+
jQuery's API is inherently functional in several ways:
|
|
58
|
+
|
|
59
|
+
### Chaining IS Composition
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// jQuery chaining = function composition without pipe()
|
|
63
|
+
$('.user-card')
|
|
64
|
+
.filter('.active')
|
|
65
|
+
.find('.username')
|
|
66
|
+
.addClass('highlighted')
|
|
67
|
+
.text(function(i, text) { return text.toUpperCase(); });
|
|
68
|
+
|
|
69
|
+
// Each method takes input, returns output (the jQuery object)
|
|
70
|
+
// This IS composition — no custom pipe() needed
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### $.map and $.grep ARE Declarative
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// jQuery's functional utilities
|
|
77
|
+
var activeNames = $.map($('.user'), function(el) {
|
|
78
|
+
return $(el).data('active') ? $(el).text() : null;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// $.grep = filter
|
|
82
|
+
var admins = $.grep(users, function(user) {
|
|
83
|
+
return user.role === 'admin';
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Prefer native Array methods for plain data:
|
|
87
|
+
var activeNames = users.filter(u => u.active).map(u => u.name);
|
|
88
|
+
// Use $.map/$.grep when working with jQuery collections
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Pure Logic Extraction (The FP Core)
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
(function($) {
|
|
95
|
+
'use strict';
|
|
96
|
+
|
|
97
|
+
// PURE: Business logic — testable, no DOM
|
|
98
|
+
function calculateShipping(weight, zone) {
|
|
99
|
+
var rates = { domestic: 0.5, international: 1.2 };
|
|
100
|
+
return Math.max(0, weight) * (rates[zone] || rates.domestic);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function formatPrice(amount) {
|
|
104
|
+
return '$' + Math.max(0, amount).toFixed(2);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// IMPURE: DOM wrapper — uses jQuery, calls pure functions
|
|
108
|
+
function ShippingCalculator($container) {
|
|
109
|
+
this.$container = $container;
|
|
110
|
+
this.$container.on('change', 'select, input', this.update.bind(this));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
ShippingCalculator.prototype.update = function() {
|
|
114
|
+
var weight = parseFloat(this.$container.find('[name="weight"]').val()) || 0;
|
|
115
|
+
var zone = this.$container.find('[name="zone"]').val();
|
|
116
|
+
var cost = calculateShipping(weight, zone);
|
|
117
|
+
this.$container.find('.shipping-cost').text(formatPrice(cost));
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Init
|
|
121
|
+
$('.shipping-calculator').each(function() {
|
|
122
|
+
new ShippingCalculator($(this));
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Export pure functions for testing
|
|
126
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
127
|
+
module.exports = { calculateShipping: calculateShipping, formatPrice: formatPrice };
|
|
128
|
+
}
|
|
129
|
+
})(jQuery);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Quick Reference
|
|
133
|
+
|
|
134
|
+
### IIFE Wrapper (WordPress Standard)
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
// Always use this pattern in WordPress — avoids $ conflicts
|
|
138
|
+
(function($) {
|
|
139
|
+
'use strict';
|
|
140
|
+
|
|
141
|
+
// All jQuery code here, $ is safe
|
|
142
|
+
|
|
143
|
+
})(jQuery);
|
|
144
|
+
|
|
145
|
+
// Shorthand document ready
|
|
146
|
+
jQuery(function($) {
|
|
147
|
+
// DOM ready, $ is safe
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Selectors and Traversal
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
// Selecting
|
|
155
|
+
$('.class') // By class
|
|
156
|
+
$('#id') // By ID
|
|
157
|
+
$('[data-action="delete"]') // By attribute
|
|
158
|
+
$('.parent .child') // Descendant
|
|
159
|
+
$('.item:first') // Pseudo-selector
|
|
160
|
+
$('input[type="text"]') // Attribute selector
|
|
161
|
+
|
|
162
|
+
// Traversal (chained)
|
|
163
|
+
$('.item')
|
|
164
|
+
.closest('.container') // Up: nearest ancestor matching selector
|
|
165
|
+
.find('.target') // Down: descendants matching selector
|
|
166
|
+
.siblings('.active') // Sideways: siblings matching selector
|
|
167
|
+
.parent() // Up: direct parent
|
|
168
|
+
.children('.row') // Down: direct children only
|
|
169
|
+
.first() // Filter: first in set
|
|
170
|
+
.filter('.visible') // Filter: matching selector
|
|
171
|
+
.not('.disabled') // Filter: exclude matching
|
|
172
|
+
.eq(2) // Filter: by index
|
|
173
|
+
|
|
174
|
+
// Context-scoped selection (efficient)
|
|
175
|
+
var $form = $('#my-form');
|
|
176
|
+
$form.find('.field') // Only searches within $form
|
|
177
|
+
$form.find('input').val() // Get value within scope
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### DOM Manipulation
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
// Classes
|
|
184
|
+
$el.addClass('active')
|
|
185
|
+
$el.removeClass('loading')
|
|
186
|
+
$el.toggleClass('visible')
|
|
187
|
+
$el.hasClass('hidden') // Returns boolean
|
|
188
|
+
|
|
189
|
+
// Content
|
|
190
|
+
$el.text('Plain text') // Set text (escapes HTML)
|
|
191
|
+
$el.html('<strong>HTML</strong>') // Set HTML
|
|
192
|
+
$el.val() // Get form value
|
|
193
|
+
$el.val('new value') // Set form value
|
|
194
|
+
|
|
195
|
+
// Attributes and Data
|
|
196
|
+
$el.attr('href') // Get attribute
|
|
197
|
+
$el.attr('href', '/new-url') // Set attribute
|
|
198
|
+
$el.prop('checked', true) // Set property (for checkboxes, disabled, etc.)
|
|
199
|
+
$el.data('user-id') // Get data-* attribute (cached, parsed)
|
|
200
|
+
$el.removeAttr('disabled')
|
|
201
|
+
|
|
202
|
+
// DOM insertion
|
|
203
|
+
$container.append($newElement) // Add inside, at end
|
|
204
|
+
$container.prepend($newElement) // Add inside, at start
|
|
205
|
+
$el.after($sibling) // Add outside, after
|
|
206
|
+
$el.before($sibling) // Add outside, before
|
|
207
|
+
$el.wrap('<div class="wrapper"></div>')
|
|
208
|
+
$el.remove() // Remove from DOM
|
|
209
|
+
$el.empty() // Remove children
|
|
210
|
+
$el.clone() // Deep clone
|
|
211
|
+
|
|
212
|
+
// CSS and Display
|
|
213
|
+
$el.css('color', 'red') // Set single property
|
|
214
|
+
$el.css({ color: 'red', fontSize: '14px' }) // Set multiple
|
|
215
|
+
$el.show() // display: previous value
|
|
216
|
+
$el.hide() // display: none
|
|
217
|
+
$el.toggle() // Toggle visibility
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Events
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
// Binding
|
|
224
|
+
$el.on('click', handler) // Direct bind
|
|
225
|
+
$container.on('click', '.child', handler) // Delegated (dynamic content!)
|
|
226
|
+
$el.off('click', handler) // Unbind specific
|
|
227
|
+
$el.off('click') // Unbind all click
|
|
228
|
+
|
|
229
|
+
// Common events
|
|
230
|
+
$el.on('click', fn)
|
|
231
|
+
$el.on('change', fn) // Form elements
|
|
232
|
+
$el.on('submit', fn) // Forms
|
|
233
|
+
$el.on('keyup', fn)
|
|
234
|
+
$el.on('input', fn) // Real-time input tracking
|
|
235
|
+
$el.on('focus blur', fn) // Multiple events
|
|
236
|
+
|
|
237
|
+
// Event object
|
|
238
|
+
$el.on('click', function(e) {
|
|
239
|
+
e.preventDefault(); // Stop default behavior
|
|
240
|
+
e.stopPropagation(); // Stop bubbling
|
|
241
|
+
var $this = $(this); // Cache $(this)
|
|
242
|
+
var data = $this.data('id');
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Namespaced events (clean removal)
|
|
246
|
+
$el.on('click.myPlugin', handler);
|
|
247
|
+
$el.off('.myPlugin'); // Remove all myPlugin events
|
|
248
|
+
|
|
249
|
+
// One-time events
|
|
250
|
+
$el.one('click', handler); // Fires once, then auto-unbinds
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### AJAX
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
// Standard WordPress AJAX
|
|
257
|
+
$.ajax({
|
|
258
|
+
url: myVars.ajaxUrl, // wp_localize_script value
|
|
259
|
+
type: 'POST',
|
|
260
|
+
data: {
|
|
261
|
+
action: 'my_action', // WordPress action hook
|
|
262
|
+
nonce: myVars.nonce, // Security token
|
|
263
|
+
id: itemId
|
|
264
|
+
},
|
|
265
|
+
success: function(response) {
|
|
266
|
+
if (response.success) {
|
|
267
|
+
// response.data contains the payload
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
error: function(xhr, status, error) {
|
|
271
|
+
console.error('AJAX failed:', error);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Shorthand GET
|
|
276
|
+
$.get(myVars.restUrl + '/items', function(data) {
|
|
277
|
+
renderItems(data);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Shorthand POST
|
|
281
|
+
$.post(myVars.ajaxUrl, { action: 'save_item', data: formData }, function(response) {
|
|
282
|
+
handleResponse(response);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Promise-style (chainable)
|
|
286
|
+
$.ajax({ url: '/api/data', dataType: 'json' })
|
|
287
|
+
.done(function(data) { /* success */ })
|
|
288
|
+
.fail(function(xhr) { /* error */ })
|
|
289
|
+
.always(function() { /* cleanup */ });
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Utilities
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
// Iteration
|
|
296
|
+
$.each(array, function(index, value) { });
|
|
297
|
+
$.each(object, function(key, value) { });
|
|
298
|
+
$('.items').each(function(index) {
|
|
299
|
+
var $this = $(this); // Cache for performance
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Type checking — prefer native equivalents
|
|
303
|
+
Array.isArray(val) // Not $.isArray (deprecated)
|
|
304
|
+
typeof val === 'string' // Not $.type (deprecated)
|
|
305
|
+
val != null // Not $.isNullOrUndefined
|
|
306
|
+
|
|
307
|
+
// Object merge (deep copy)
|
|
308
|
+
var merged = $.extend(true, {}, defaults, options);
|
|
309
|
+
|
|
310
|
+
// Serialize form data
|
|
311
|
+
var data = $form.serialize(); // URL-encoded string
|
|
312
|
+
var dataArray = $form.serializeArray(); // Array of {name, value}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Common Patterns
|
|
316
|
+
|
|
317
|
+
### Cache jQuery Selections
|
|
318
|
+
|
|
319
|
+
```javascript
|
|
320
|
+
// BAD: Re-querying DOM repeatedly
|
|
321
|
+
$('.my-element').addClass('active');
|
|
322
|
+
$('.my-element').find('.child').show();
|
|
323
|
+
$('.my-element').data('loaded', true);
|
|
324
|
+
|
|
325
|
+
// GOOD: Cache the selection
|
|
326
|
+
var $el = $('.my-element');
|
|
327
|
+
$el.addClass('active');
|
|
328
|
+
$el.find('.child').show();
|
|
329
|
+
$el.data('loaded', true);
|
|
330
|
+
|
|
331
|
+
// BEST: Chain when possible
|
|
332
|
+
$('.my-element')
|
|
333
|
+
.addClass('active')
|
|
334
|
+
.find('.child').show()
|
|
335
|
+
.end() // Go back to .my-element
|
|
336
|
+
.data('loaded', true);
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Delegated Events for Dynamic Content
|
|
340
|
+
|
|
341
|
+
```javascript
|
|
342
|
+
// BAD: Won't work for dynamically added elements
|
|
343
|
+
$('.delete-btn').on('click', handleDelete);
|
|
344
|
+
|
|
345
|
+
// GOOD: Delegated — works for current AND future elements
|
|
346
|
+
$('.item-list').on('click', '.delete-btn', handleDelete);
|
|
347
|
+
|
|
348
|
+
// Use delegation when:
|
|
349
|
+
// - Elements are added/removed dynamically (AJAX, repeaters)
|
|
350
|
+
// - Many identical handlers (performance — one handler vs hundreds)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### UI State Management
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
(function($) {
|
|
357
|
+
'use strict';
|
|
358
|
+
|
|
359
|
+
// Pure: Compute next state
|
|
360
|
+
function getToggleState($el) {
|
|
361
|
+
return !$el.hasClass('is-open');
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Impure: Apply state to DOM
|
|
365
|
+
function applyToggleState($trigger, $target, isOpen) {
|
|
366
|
+
$trigger.attr('aria-expanded', isOpen);
|
|
367
|
+
$target.toggleClass('is-open', isOpen);
|
|
368
|
+
if (isOpen) {
|
|
369
|
+
$target.slideDown(200);
|
|
370
|
+
} else {
|
|
371
|
+
$target.slideUp(200);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Wire up
|
|
376
|
+
$('.accordion').on('click', '.accordion-trigger', function(e) {
|
|
377
|
+
e.preventDefault();
|
|
378
|
+
var $trigger = $(this);
|
|
379
|
+
var $target = $($trigger.data('target'));
|
|
380
|
+
applyToggleState($trigger, $target, getToggleState($target));
|
|
381
|
+
});
|
|
382
|
+
})(jQuery);
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Anti-Patterns
|
|
386
|
+
|
|
387
|
+
| Anti-Pattern | Problem | Fix |
|
|
388
|
+
|---|---|---|
|
|
389
|
+
| Vanilla JS when jQuery is loaded | Verbose, inconsistent | Use jQuery for DOM work |
|
|
390
|
+
| `document.querySelectorAll` + `forEach` in WP | Ignores available jQuery | `$('.selector').each()` |
|
|
391
|
+
| Mixing jQuery and vanilla in same file | Inconsistent, confusing | Pick one per file |
|
|
392
|
+
| Not caching `$(this)` in loops | Re-wraps DOM element each time | `var $this = $(this)` |
|
|
393
|
+
| `$('.selector')` inside loops | Re-queries DOM each iteration | Cache outside loop |
|
|
394
|
+
| Direct binding on dynamic elements | Handlers lost on DOM change | Use delegated `.on()` |
|
|
395
|
+
| Creating custom `pipe()` / `compose()` | Over-engineering | jQuery chaining IS composition |
|
|
396
|
+
|
|
397
|
+
## Integration
|
|
398
|
+
|
|
399
|
+
- **js-fp**: Core FP principles (purity, immutability, testing). jQuery DOM code follows these — pure logic extracted, side effects in DOM wrapper.
|
|
400
|
+
- **js-fp-wordpress**: WordPress-specific integration (GF hooks, ACF hooks, admin JS). References this skill for jQuery patterns.
|
|
401
|
+
- **ima-bootstrap**: Bootstrap 5 JS components. jQuery available but BS5 doesn't require it — use for custom enhancements.
|
|
402
|
+
- **Context7**: For deep jQuery API lookups use library ID `/jquery/jquery`.
|
|
403
|
+
|
|
404
|
+
## WordPress Coding Standards
|
|
405
|
+
|
|
406
|
+
Per WordPress JS coding standards:
|
|
407
|
+
- Use tabs for indentation
|
|
408
|
+
- IIFE wrapper with `jQuery` passed as `$`
|
|
409
|
+
- `'use strict'` inside the IIFE
|
|
410
|
+
- Spaces inside parentheses: `if ( condition )` not `if (condition)`
|
|
411
|
+
- `var` declarations at top of scope (unless using build tools with ES6+)
|
|
412
|
+
|
|
413
|
+
See [WordPress JavaScript Coding Standards](https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/) for full reference.
|