feat: archive zoo_backup for home sync

This commit is contained in:
Patrick Plate
2026-06-24 19:27:05 +02:00
parent 02844e4c4a
commit 038e546963
133 changed files with 19953 additions and 0 deletions
+158
View File
@@ -0,0 +1,158 @@
---
name: code-review
description: Structured code review against implementation plan.
---
# Skill: code-review
Structured code review against implementation plan.
## Invoked by
🔍 Reviewer mode
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
## Output
Markdown file: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-review.md`
## Steps
### 1. Read the plan document
```bash
cat docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-plan.md
```
Extract: planned changes, affected files, expected patterns, acceptance criteria.
### 2. Read the test plan (if exists)
```bash
cat docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-testplan.md
```
Cross-reference: are all planned test cases implemented?
### 3. Get the diff
```bash
cd <your-repo-path>-<TICKET_KEY>
git diff origin/main --name-only
git diff origin/main --stat
git diff origin/main
```
### 4. Read changed files
For each changed file, read the full file to understand context — not just the diff hunks.
### 5. Run the review checklist
For each changed file, verify:
| # | Check | What to look for |
|---|-------|-----------------|
| 1 | Plan compliance | All plan items implemented? Nothing missing, nothing extra? |
| 2 | Pattern correctness | Correct project patterns used? |
| 3 | No generated source changes | Generated sources must never be modified manually |
| 4 | Logging | Parameterized messages (`log.debug("x: {}", v)`) — no string concatenation |
| 5 | Error handling | Proper error responses checked before parsing? Null-safe patterns? |
| 6 | Test coverage | Every new/modified public method has a test? Edge cases covered? |
| 7 | Database migrations | Correct naming convention? Dual DB dialect support? |
| 8 | No hardcoded values | No hardcoded IDs, instance names, or secrets? |
| 9 | Field visibility | Appropriate access modifiers? |
| 10 | Annotations | Correct use of framework annotations? |
### 6. Check test quality
For each test file:
- Meaningful assertions (not just `assertNotNull`)?
- Edge cases covered?
- Mocking done correctly?
- Test naming convention: `test<What>_<Scenario>_<Expected>()`?
### 7. Run tests
```bash
cd <your-repo-path>-<TICKET_KEY>
mvn test -pl <module-path> -f pom.xml
```
### 8. Generate review document
```markdown
# Code Review: <TICKET_KEY> — <Summary>
**Date:** <today>
**Module:** <MODULE>
**Reviewer:** Lumen (Reviewer)
**Branch:** <branch name>
**Status:** ✅ Approved / ⚠️ Approved with comments / ❌ Changes requested
---
## Summary
<1-2 sentence summary of the review outcome>
## Reviewed Files
| File | Change | Assessment |
|------|--------|-----------|
| `<path>` | New/Modified | ✅ / ⚠️ / ❌ |
## Checklist
| # | Check | Result | Note |
|---|-------|--------|------|
| 1 | Plan compliance | ✅ | All planned changes implemented |
| ... | ... | ... | ... |
## Findings
### ⚠️ Warnings (non-blocking)
1. **<file>:<line>** — <description>
- Recommendation: <suggested fix>
### ❌ Blockers (must fix)
1. **<file>:<line>** — <description>
- Reason: <why this must be fixed>
## Tests
- **Executed:** <N> tests
- **Passed:** <N> ✅
- **Failed:** <N> ❌
- **Build:** ✅ Green / ❌ Red
## Recommendation
<Final recommendation: merge / fix and re-review / reject>
```
### 9. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Code review completed — {status}. {findings_count} findings ({blockers} blockers)."
)
```
## Severity Levels
| Level | Symbol | Meaning | Action |
|-------|--------|---------|--------|
| Blocker | ❌ | Must fix before merge | Changes requested |
| Warning | ⚠️ | Should fix, not blocking | Approved with comments |
| Info | ️ | Suggestion for improvement | Approved |
| OK | ✅ | No issues | — |
+143
View File
@@ -0,0 +1,143 @@
---
name: create-pr
description: Create a Bitbucket pull request from a worktree branch.
---
# Skill: create-pr
Create a Bitbucket (or GitHub) pull request from a worktree branch.
## Invoked by
🎫 JiraOps mode (or 🪃 Orchestrator)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
## Output
- Pull request created targeting the main branch
- Jira comment with PR link added
- BigMind fact stored
## Steps
### 1. Get current branch
```bash
cd <your-repo-path>-<TICKET_KEY>
git branch --show-current
```
### 2. Ensure all changes are committed
```bash
git status
```
If uncommitted changes exist, warn the user before proceeding.
### 3. Push branch to origin
```bash
git push -u origin <BRANCH>
```
### 4. Gather diff statistics
```bash
git diff origin/main --stat
git diff origin/main --name-only
```
### 5. Read Jira ticket for context
```python
ticket = retrieve_ticket_details(TICKET_KEY)
# Extract: summary, description for PR title/description
```
### 6. Compose PR title and description
PR title format:
```
<TICKET_KEY>: <Jira summary>
```
PR description template:
```markdown
## Jira
<TICKET_KEY>: <summary>
## Description
<Brief description of what was changed and why>
## Changes
<List of changed files grouped by component>
## Tests
- <N> Unit tests
- <M> Integration tests
- All tests passing ✅
## Checklist
- [ ] Code review completed
- [ ] Tests passing
- [ ] No generated source modifications
```
### 7. Create the pull request
```python
create_pull_request(
project_key="<PROJECT>",
repo_slug="<repo>",
title=f"{TICKET_KEY}: {summary}",
description=<composed description>,
from_branch=<BRANCH>,
to_branch="main"
)
```
### 8. Add Jira comment with PR link
```python
add_comment_to_ticket(
issue_key=TICKET_KEY,
comment=f"*Pull Request created*\n\nBranch: {BRANCH}\nPR: [PR #{pr_id}|<pr_url>]"
)
```
### 9. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: PR #{pr_id} created — {BRANCH} → main. {N} files changed."
)
```
## Error Handling
| Error | Resolution |
|-------|------------|
| Branch not pushed | Run `git push -u origin <BRANCH>` first |
| Uncommitted changes | Warn user, suggest `git add` + `git commit` |
| PR already exists | Check `list_prs_for_repository` for existing PR from same branch |
| Merge conflicts | Run `git fetch origin main && git merge origin/main` in worktree |
| No diff (empty PR) | Branch is identical to `main` — nothing to merge |
## Conventions
- PR title: always starts with `TICKET_KEY:` for Jira auto-linking
- Target branch: typically `main` (configure per project)
- One PR per ticket — don't create multiple PRs for the same branch
@@ -0,0 +1,154 @@
---
name: create-worktree
description: Git worktree setup for a Jira ticket. Supports multi-branch strategy with automatic base branch selection. Use when asked to create a worktree, start work on a ticket, or set up a branch for a Jira issue.
---
# Skill: create-worktree
Git worktree setup for a Jira ticket with correct base branch selection.
## When to use
- User asks to create a worktree for a Jira ticket
- User asks to "start work on" or "set up" a ticket
- Orchestrator delegates worktree creation for a new ticket
## When NOT to use
- Switching to an existing worktree → use `switch-worktree` skill
- Removing a worktree after merge → see Cleanup section below
## Invoked by
🎫 JiraOps mode (or 🪃 Orchestrator)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_ID` | Jira issue key | `PROJECT-123` |
| `MODULE` | Ticket context or user input | Module/component name |
| `TYPE` | Ticket issue type (Story → feature, Bug → bugfix) | `feature` or `bugfix` |
| `SHORT_DESC` | Kebab-case summary (2-4 words) | `fix-auth-timeout` |
| `BASE_BRANCH` | (Optional) Long-lived branch to base work on | `main` (default) |
## Branch Strategy
| Branch | Purpose | Use as base when... |
|--------|---------|-------------------|
| `main` | Current development — **DEFAULT** | Standard features, bugs, tasks |
| `release` | Current production release (hotfixes) | Urgent hotfixes for production |
### Base branch → worktree branch prefix mapping
| BASE_BRANCH | Allowed TYPE | Branch prefix |
|-------------|-------------|---------------|
| `main` | `feature` or `bugfix` | `feature/...` or `bugfix/...` |
| `release` | `bugfix` only | `hotfix/...` |
## Steps
### 1. Parse ticket metadata
```
TICKET_KEY = e.g. "PROJECT-123"
```
If MODULE or TYPE are not provided, retrieve them from Jira:
- `retrieve_ticket_details(TICKET_KEY)` → read `issuetype` and `summary`
- Map issue type: `Story` / `Task``feature`, `Bug``bugfix`
- Infer module from summary keywords or ask the user
### 2. Determine base branch
If `BASE_BRANCH` is not explicitly provided, apply this decision logic:
1. **Default:** `main`
2. **If user says "hotfix" or ticket priority is Critical/Blocker:** suggest `release`
When suggesting a non-default base, confirm with the user before proceeding.
### 3. Determine branch name
```
BRANCH = <TYPE>/<MODULE>/<TICKET_KEY>-<SHORT_DESC>
```
Examples:
- `feature/auth/PROJECT-123-oauth2-timeout`
- `bugfix/api/PROJECT-456-null-pointer`
- `hotfix/api/PROJECT-789-critical-fix` (base: `release`)
### 4. Ensure base branch is up to date
```bash
cd <your-repo-path>
git fetch origin <BASE_BRANCH>
```
### 5. Create worktree
```bash
git worktree add <your-repo-path>-<TICKET_KEY> -b <BRANCH> origin/<BASE_BRANCH>
```
This creates:
- Worktree directory: `<your-repo-path>-<TICKET_KEY>`
- New branch: `<BRANCH>` tracking `origin/<BASE_BRANCH>`
### 6. Verify
```bash
cd <your-repo-path>-<TICKET_KEY> && git branch --show-current
```
### 7. Switch VS Code workspace to worktree
```bash
code --reuse-window <your-repo-path>-<TICKET_KEY>
```
### 8. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Worktree at <path>, branch {BRANCH}, based on {BASE_BRANCH}"
)
```
### 9. Announce focus
```python
memory_announce_focus(
session_id=SESSION_ID,
description=f"Working on {TICKET_KEY} in worktree",
files=[target_path],
ide_hint="Roo"
)
```
## Expected Output
- Worktree directory exists
- Branch is checked out, based on `origin/<BASE_BRANCH>`
- VS Code workspace switched to worktree directory
- BigMind fact stored with worktree path and base branch
- Focus announced
## Error Handling
| Error | Resolution |
|-------|------------|
| Worktree already exists | Check if branch matches. If yes, reuse. If no, ask user. |
| Branch already exists | `git worktree add <path> <BRANCH>` (without `-b`) |
| `origin/<BASE_BRANCH>` not found | Try `git fetch origin` first, then retry |
| Directory already exists (not a worktree) | Ask user to remove or choose different path |
## Cleanup (when ticket is done)
```bash
cd <your-repo-path>
git worktree remove <your-repo-path>-<TICKET_KEY>
git branch -d <BRANCH> # only after merge
```
@@ -0,0 +1,122 @@
---
name: expert-panel-review
description: Multi-expert panel review that analyzes a plan or code from 3 specialized perspectives (Domain Expert, Architecture Expert, Risk/Compliance Expert). Produces a synthesized panel verdict with confidence level. Use when reviewing plans, assessments, or code changes that need high-confidence validation.
---
# Skill: expert-panel-review
Multi-expert panel review for high-confidence validation of plans and code.
## When to use
- Reviewing plans that need multi-perspective validation
- Complex architectural decisions requiring diverse expert input
- Any change where confidence level matters before proceeding
## Invoked by
📋✅ Plan Reviewer mode (as part of plan review workflow)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `ARTIFACT_TYPE` | Type of artifact being reviewed | `plan`, `assessment`, `code` |
| `ARTIFACT_PATH` | Path to the document/code | `docs/auth/PROJECT-123/PROJECT-123-plan.md` |
## Panel Composition
### 🏛️ Domain Expert
- Validates business logic correctness
- Checks domain terminology and workflows
- Verifies requirements are fully addressed
- Identifies missing business rules
### 🔧 Architecture Expert
- Validates technical design patterns
- Checks for scalability and maintainability concerns
- Verifies integration points are handled correctly
- Identifies missing error handling or edge cases
### 🛡️ Risk/Compliance Expert
- Identifies security implications
- Checks for data privacy concerns
- Validates audit trail requirements
- Flags regulatory compliance gaps
## Steps
### 1. Load the artifact
Read the document at `ARTIFACT_PATH` completely.
### 2. Domain Expert review
Analyze from the domain perspective:
- Are all business requirements addressed?
- Is domain terminology used correctly?
- Are business rules complete and accurate?
- Are there missing edge cases from a domain perspective?
Output: findings list + confidence score (0-100%)
### 3. Architecture Expert review
Analyze from the technical perspective:
- Are design patterns appropriate?
- Is the solution maintainable and testable?
- Are integration points correctly handled?
- Are failure modes addressed?
Output: findings list + confidence score (0-100%)
### 4. Risk/Compliance Expert review
Analyze from a risk perspective:
- Are there security implications?
- Is data handling appropriate?
- Are there compliance requirements being missed?
- What's the blast radius if something goes wrong?
Output: findings list + confidence score (0-100%)
### 5. Synthesize panel verdict
Combine all three perspectives:
```markdown
## Panel Verdict
**Overall Confidence:** <avg of 3 scores>%
- Domain: <score>% — <1-line summary>
- Architecture: <score>% — <1-line summary>
- Risk: <score>% — <1-line summary>
### Blockers (❌)
<items all experts agree must be fixed>
### Warnings (⚠️)
<items raised by 1-2 experts as concerns>
### Recommendations (️)
<suggestions for improvement>
```
### 6. Confidence interpretation
| Confidence | Meaning | Action |
|-----------|---------|--------|
| 90-100% | High confidence — safe to proceed | APPROVED |
| 70-89% | Good confidence — minor concerns | APPROVED with warnings |
| 50-69% | Mixed signals — significant concerns | REVISE recommended |
| < 50% | Low confidence — major gaps | REVISE required |
## Output Format
The panel review is embedded in the parent review document (plan-review.md or code-review.md), not as a standalone file.
## Notes
- Panel confidence < 70% → parent review MUST be REVISE regardless of checklist
- All three experts must produce findings — even if "no concerns" is the finding
- Disagreements between experts should be highlighted explicitly
@@ -0,0 +1,136 @@
---
name: generate-handover
description: Generate handover document for session or person transfer.
---
# Skill: generate-handover
Generate handover document for session or person transfer.
## Invoked by
📝 DocGen mode (or 🪃 Orchestrator)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
| `SESSION_ID` | BigMind session to hand over (optional) | `d8a0f4fa-...` |
## Output
Markdown file: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-handover-<date>.md`
## Steps
### 1. Read BigMind session context
```python
memory_get_session_detail(session_id=SESSION_ID)
memory_search_facts("<TICKET_KEY>")
memory_search_chunks("<TICKET_KEY>")
```
### 2. Read git status
```bash
cd <worktree-path>
git branch --show-current
git status
git log origin/main..HEAD --oneline
git diff origin/main --stat
```
### 3. Read Jira ticket status
```python
ticket = retrieve_ticket_details(TICKET_KEY)
checklist = get_checklist(TICKET_KEY)
```
### 4. Read existing documentation
Check `docs/<MODULE>/<TICKET_KEY>/` for assessment, plan, testplan, solution, review docs.
### 5. Analyze what's done vs. remaining
Cross-reference Jira checklist, git commits, test plan status, and plan steps.
### 6. Generate handover document
```markdown
# Handover: <TICKET_KEY> — <Summary>
**Date:** <today>
**Module:** <MODULE>
**Author:** Lumen (DocGen)
**BigMind Session:** `<SESSION_ID>`
**Branch:** <current branch>
---
## 1. Current State
**Jira Status:** <status>
**Progress:** <X>/<Y> checklist items complete
<1-3 sentence summary>
## 2. Completed Work
| # | Description | Files | Commit |
|---|------------|-------|--------|
| 1 | <what was done> | `<file1>`, `<file2>` | `<hash>` |
## 3. Remaining Work
| # | Description | Priority | Estimated Effort |
|---|------------|----------|-----------------|
| 1 | <what remains> | High/Medium/Low | <estimate> |
## 4. Open Questions / Blockers
| # | Question/Blocker | Context | Contact |
|---|-----------------|---------|---------|
| 1 | <question> | <context> | <who> |
## 5. Key Decisions
| Decision | Rationale | Date |
|----------|----------|------|
| <decision> | <why> | <date> |
## 6. Technical Notes
- <Important context the next person needs>
- <Environment setup needed>
- <Test data requirements>
## 7. Context Recovery
For continuing this work:
- **Worktree:** `<path>`
- **Branch:** `<branch name>`
- **BigMind Session:** `<SESSION_ID>``memory_get_session_detail("<ID>")` for details
- **Documentation:** `docs/<MODULE>/<TICKET_KEY>/`
```
### 7. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Handover doc created. Status: {done}/{total} items done."
)
```
## When to Use
| Scenario | Trigger |
|----------|---------|
| End of day | Capture progress before stopping work |
| Person transfer | Handing ticket to another developer |
| Session recovery | After IDE crash, use to restore context |
| Long pause | Before vacation or multi-day break |
@@ -0,0 +1,135 @@
---
name: generate-solution-doc
description: Solution documentation from implementation results.
---
# Skill: generate-solution-doc
Solution documentation from implementation results.
## Invoked by
📝 DocGen mode
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
| `PLAN_PATH` | Path to plan.md | `docs/auth/PROJECT-123/PROJECT-123-plan.md` |
| `TESTPLAN_PATH` | Path to testplan.md | `docs/auth/PROJECT-123/PROJECT-123-testplan.md` |
## Output
- Markdown: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-solution.md`
- PDF: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-solution.pdf`
## Steps
### 1. Read input documents
Read all available docs in `docs/<MODULE>/<TICKET_KEY>/`.
### 2. Analyze actual changes
```bash
cd <worktree-path>
git diff origin/main --stat
git diff origin/main --name-only
git log origin/main..HEAD --oneline
```
### 3. Gather test results
Check surefire reports or reference the testplan status.
### 4. Generate solution document
```markdown
# Solution Documentation: <TICKET_KEY>
**Date:** <today>
**Module:** <MODULE>
**Author:** <Your Name>
**Jira:** <TICKET_KEY>
**Branch:** <branch name>
---
## 1. Problem Statement
<What was the problem? Why did it need solving?>
## 2. Approach
<High-level approach chosen. Reference the plan document.>
## 3. Architecture Decisions
| Decision | Rationale | Alternatives |
|----------|----------|--------------|
| <decision> | <why> | <what was considered> |
## 4. Implemented Changes
### 4.1 <Component group>
| File | Change | Description |
|------|--------|-------------|
| `<path>` | New/Modified | <what changed> |
### 4.n Database Migrations
| Migration | Database | Description |
|-----------|----------|-------------|
| `V{timestamp}__...` | H2/Oracle | <what it does> |
## 5. Test Coverage
| ID | Description | Type | Result |
|----|-------------|------|--------|
| T-01 | <desc> | Unit | ✅ |
| T-02 | <desc> | Integration | ✅ |
## 6. Open Items
| # | Description | Priority | Ticket |
|---|-------------|----------|--------|
| 1 | <open item> | High/Medium/Low | <linked ticket or "—"> |
```
### 5. Ask for PDF color scheme
> "Which color scheme for the PDF? Available: adp (red), royal_purple, ocean, forest, sunset, slate, rose"
### 6. Generate PDF
```python
generate_pdf(
content=<markdown content>,
title=f"Solution Documentation {TICKET_KEY}",
author="Your Name",
output_path=f"docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-solution.pdf",
color_scheme=<chosen scheme>
)
```
### 7. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Solution doc created, PDF generated"
)
```
## Template Variants
### Minimal (for small bugfixes)
Skip sections 3 (Architecture Decisions) and 6 (Open Items). Keep 1, 2, 4, 5.
### Extended (for large features)
Add: Configuration Changes, Deployment Notes, Backward Compatibility, Performance Impact.
@@ -0,0 +1,123 @@
---
name: generate-testplan
description: Structured test plan from implementation plan / assessment.
---
# Skill: generate-testplan
Structured test plan from implementation plan / assessment.
## Invoked by
📋 Planner mode
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
| `PLAN_PATH` | Path to plan.md | `docs/auth/PROJECT-123/PROJECT-123-plan.md` |
## Output
Markdown file: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-testplan.md`
## Steps
### 1. Read the implementation plan
Understand which classes/methods are being added or modified, data flows affected, database changes, and integration points.
### 2. Identify testable units
| Category | What to test | Test type |
|----------|-------------|-----------|
| New methods | Input/output, edge cases, null handling | Unit |
| Modified methods | Regression + new behavior | Unit |
| Database changes | Migration up/down, data integrity | Integration |
| Data flows | End-to-end processing | Integration |
| Error paths | Invalid input, missing data, error responses | Unit |
### 3. Generate test plan document
```markdown
# Test Plan: <TICKET_KEY> — <Summary>
**Date:** <today>
**Module:** <MODULE>
**Author:** Lumen (Planner)
**Status:** Draft v1
**Based on:** <TICKET_KEY>-plan.md
---
## Test Overview
| ID | Description | Type | Class | Status |
|----|-------------|------|-------|--------|
| T-01 | <short desc> | Unit | <TestClass> | ⬜ |
| T-02 | <short desc> | Unit | <TestClass> | ⬜ |
| T-03 | <short desc> | Integration | <TestClass> | ⬜ |
Status: ⬜ Open | ✅ Passed | ❌ Failed | ⏭️ Skipped
---
## Test Cases
### T-01: <Descriptive name>
**Type:** Unit
**Class:** `<package>.<TestClassName>`
**Method:** `test<MethodName>()`
**Preconditions:**
- <setup requirements>
**Scenarios:**
| # | Input | Expected Result |
|---|-------|----------------|
| a | <input> | <expected> |
| b | <input> | <expected> |
| c | <edge case> | <expected> |
---
## Test Data
<Describe test data requirements, fixtures, or database setup needed.>
## Test Coverage
| Component | Unit | Integration | Total |
|-----------|------|-------------|-------|
| <Class1> | 3 | 1 | 4 |
| <Class2> | 2 | 0 | 2 |
| **Total** | **5** | **1** | **6** |
```
### 4. Cross-reference with plan
Verify every implementation step has at least one test case. Flag gaps as warnings.
### 5. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Testplan with {N} test cases (Unit: {u}, Integration: {i})"
)
```
## Test Naming Conventions
- Test class: `<OriginalClass>Test.java` or `<Feature>Test.java`
- Test method: `test<What>_<Scenario>_<Expected>()` or `test<What>()` for simple cases
- Location: mirror source structure under `src/test/java/`
## Test ID Format
- Sequential: T-01, T-02, ..., T-nn
- IDs are stable — don't renumber on revision, append new tests at the end
+173
View File
@@ -0,0 +1,173 @@
---
name: mvn-test
description: Run Maven tests in multi-module projects. Resolves module paths, builds dependencies, parses surefire XML reports, and returns structured pass/fail results. Use when asked to run tests, execute test classes, or verify a module build.
---
# Maven Test & Build Runner
## When to use
- Running all tests for a module in a multi-module Maven project
- Running a specific test class or method
- Building a fat JAR for deployment
- Verifying a build after code changes in a worktree
- Troubleshooting Maven dependency/version issues
## When NOT to use
- SSH integration tests on remote instances → use a dedicated SSH test skill
- Creating new test files → use Code mode directly
- Running non-Maven tests (npm, etc.)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Issue key or task ID | `PROJECT-123` |
| `MODULE` | Maven module name | `module-a`, `module-b`, `persistence` |
| `TEST_CLASS` | Fully qualified test class (optional) | `com.example.service.MyServiceTest` |
## Module Path Resolution
| Module name | Maven `-pl` path |
|------------|-----------------|
| module-a | `java/modules/cs-modules/module-a` |
| module-b | `java/modules/cs-modules/module-b` |
| nested-module | `java/modules/cs-modules/parent-group/nested-module` |
| persistence | `java/persistence` |
| shared-lib | `java/modules/shared-lib` |
If the module is not in this table, search for it:
```bash
find java/modules -name "pom.xml" -path "*/<MODULE>/*" | head -3
```
## Workflow
### 1. Determine worktree path
```bash
WORKTREE="<your-repo-path>"
# Verify it exists
ls "$WORKTREE/java/pom.xml"
```
If no worktree exists, fall back to the main repo path
### 2. Resolve module path
Look up `MODULE` in the path resolution table above. Store as `MODULE_PATH`.
### 3. Run tests
**All module tests:**
```bash
cd <WORKTREE> && mvn test -pl <MODULE_PATH> -am -f java/pom.xml
```
**Specific test class:**
```bash
cd <WORKTREE> && mvn test -pl <MODULE_PATH> -am -Dtest="<TEST_CLASS>" -Dsurefire.failIfNoSpecifiedTests=false -f java/pom.xml
```
**Specific test method:**
```bash
cd <WORKTREE> && mvn test -pl <MODULE_PATH> -am -Dtest="<TEST_CLASS>#<methodName>" -Dsurefire.failIfNoSpecifiedTests=false -f java/pom.xml
```
### 4. Parse results
Look for these patterns in the output:
| Pattern | Meaning |
|---------|---------|
| `Tests run: N, Failures: F, Errors: E, Skipped: S` | Surefire summary |
| `BUILD SUCCESS` | All tests passed |
| `BUILD FAILURE` | At least one test failed or compilation error |
| `There are test failures` | Link to surefire reports |
If tests fail, read the surefire report:
```bash
find <WORKTREE>/<MODULE_PATH>/target/surefire-reports -name "*.txt" -exec grep -l "FAILURE\|ERROR" {} \;
```
### 5. Store results in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: mvn test {MODULE}{tests_run} run, {failures} failures, {errors} errors. {'BUILD SUCCESS' or 'BUILD FAILURE'}"
)
```
## Building Fat JARs (for deployment)
### Package a module with all dependencies:
```bash
cd <WORKTREE> && mvn package -pl :<ARTIFACT_ID> -am -DskipTests -f java/pom.xml -Drevision=1.0.0-TEST -o -q
```
### Locate the built JAR:
```bash
find <MODULE_PATH>/target -name "*-jar-with-dependencies.jar" | head -1
```
### Module artifact IDs (for `-pl :NAME`):
| Module | Artifact ID | Fat JAR name |
|--------|-------------|-------------|
| module-a | `ModuleA` | `ModuleA-*-jar-with-dependencies.jar` |
| module-b | `ModuleB` | `ModuleB-*-jar-with-dependencies.jar` |
| persistence | `persistence` | (no fat JAR) |
Use `:ARTIFACT_ID` with `-pl` for single-module builds (faster than path-based).
## Critical: Version Timestamp Issue
If the project uses a Maven `${revision}` timestamp-based SNAPSHOT scheme (e.g. `1.0-DEV-SNAPSHOT-<timestamp>`), the snapshot changes every minute; ensure dependent modules are rebuilt in the same run.
**Problem:** If you `mvn install` at 07:55 and then `mvn test` at 07:56, the version changed and artifacts can't be found.
**Solutions:**
1. **Always use `-am` (also-make)** — builds from source, no cached artifacts needed
2. **Pin the version:** `-Drevision=1.0.0-TEST` — stable across commands
3. **Use `-o` (offline)** — prevents remote lookups that fail on VPN/cert issues
4. **Never use `-pl` without `-am`** for test runs — dependencies won't resolve
### Recommended command patterns:
```bash
# Compile check (fast)
mvn compile -pl :<ARTIFACT_ID> -am -f java/pom.xml -o -q
# Run specific test (reliable)
mvn test -pl :<ARTIFACT_ID> -am -f java/pom.xml \
-Dtest="com.example.MyTest" \
-Dsurefire.failIfNoSpecifiedTests=false \
-Dmaven.test.skip=false -DskipTests=false \
-Drevision=1.0.0-TEST -o
# Build fat JAR for deployment
mvn package -pl :<ARTIFACT_ID> -am -DskipTests -f java/pom.xml \
-Drevision=1.0.0-TEST -o -q
```
### Why `-Dmaven.test.skip=false -DskipTests=false`?
Some modules have `<skipTests>true</skipTests>` in their POM or parent POM. These flags override that to force test execution.
## Troubleshooting
| Problem | Solution |
|---------|----------|
| `Could not find artifact` | Add `-am` flag to build dependencies first |
| `No tests were executed` | Check test class path — use package-relative path, not fully qualified with `src/test/java/` |
| `Compilation failure` in dependency | Run `mvn compile -pl <MODULE_PATH> -am -f java/pom.xml` first to isolate |
| OOM during tests | Add `-Xmx1g` via `MAVEN_OPTS`: `MAVEN_OPTS="-Xmx1g" mvn test ...` |
| Test hangs | Add `-Dsurefire.timeout=120` to kill stuck tests after 120s |
| `Tests are skipped` | Add `-Dmaven.test.skip=false -DskipTests=false` |
| Version mismatch (timestamp) | Pin with `-Drevision=1.0.0-TEST` |
| Certificate/SSL error on artifact download | Add `-o` (offline) — use local sources with `-am` |
| `No tests matching pattern` in dependency modules | Add `-Dsurefire.failIfNoSpecifiedTests=false` |
| Wrong module selected by `-pl` | Use artifact ID (`:ModuleA`) not path — check with `grep '<artifactId>' <MODULE_PATH>/pom.xml` |
+160
View File
@@ -0,0 +1,160 @@
---
name: plan-review
description: Plan and testplan quality review before implementation. Produces APPROVED/REVISE verdict.
---
# Skill: plan-review
Plan and testplan quality review before implementation.
## Invoked by
📋✅ Plan Reviewer mode
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `TICKET_KEY` | Jira issue key | `PROJECT-123` |
| `MODULE` | Module/component name | `auth`, `api`, `core` |
## Output
Markdown file: `docs/<MODULE>/<TICKET_KEY>/<TICKET_KEY>-plan-review.md`
## Steps
### 1. Read the planning documents
- Assessment (`*-assessment.md`) — required
- Implementation plan (`*-plan.md`) — required
- Test plan (`*-testplan.md`) — required
If any required document is missing, flag as REVISE immediately.
### 2. Read the Jira ticket
Cross-reference: do the plan documents address ALL requirements from the ticket?
### 3. Read affected source code
For each file/class mentioned in the plan:
- Verify the file exists at the stated path
- Verify class/method names are correct
- Verify patterns described match actual code
- Check if the plan missed related files
### 4. Run the plan review checklist
#### Assessment Review
| # | Check |
|---|-------|
| 1 | Problem statement complete and matches Jira ticket |
| 2 | Affected components identified — any missing? |
| 3 | Current state description matches actual code |
| 4 | Risk assessment realistic |
| 5 | Solution options evaluated with justification |
#### Implementation Plan Review
| # | Check |
|---|-------|
| 6 | All requirements covered |
| 7 | Correct project patterns referenced |
| 8 | File paths correct and exist |
| 9 | Implementation order logical (dependencies first) |
| 10 | No gaps between steps |
| 11 | Database migrations planned (if needed) |
| 12 | Error handling planned (not just happy path) |
| 13 | No scope creep beyond ticket requirements |
#### Test Plan Review
| # | Check |
|---|-------|
| 14 | Coverage complete — every plan step has a test |
| 15 | Test types appropriate (unit vs integration) |
| 16 | Edge cases covered (null, empty, boundary values) |
| 17 | Test class naming correct |
| 18 | Test method naming correct |
| 19 | Test data defined |
### 5. Run expert-panel-review skill
Before generating the verdict, run the `expert-panel-review` skill for multi-perspective analysis. Panel confidence < 70% → verdict MUST be REVISE.
### 6. Generate plan review document
```markdown
# Plan Review: <TICKET_KEY> — <Summary>
**Date:** <today>
**Module:** <MODULE>
**Reviewer:** Lumen (Plan Reviewer)
**Documents:** assessment.md v<N>, plan.md v<N>, testplan.md v<N>
**Verdict:** ✅ APPROVED / 🔄 REVISE
---
## Summary
<1-2 sentence summary>
## Checklist
| # | Check | Result | Note |
|---|-------|--------|------|
| 1 | Problem statement complete | ✅/❌ | |
| ... | ... | ... | ... |
## Findings
### ❌ Must revise (blocking)
1. **<document>** — <issue>
### ⚠️ Suggestions (non-blocking)
1. **<document>** — <suggestion>
## Traceability Matrix
| Requirement | Plan Step | Test Case | Status |
|------------|-----------|-----------|--------|
| <req 1> | Step <N> | T-<NN> | ✅ Covered |
## Verdict
**✅ APPROVED** — Plan is complete and ready for implementation.
— or —
**🔄 REVISE** — <N> items need rework. Back to Planner.
**Panel Confidence:** <X>%
```
### 7. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"{TICKET_KEY}: Plan review — {verdict}. {findings} findings ({blockers} blocking)."
)
```
## Verdict Criteria
| Verdict | Criteria |
|---------|---------|
| ✅ APPROVED | All checklist items pass. No blocking findings. Panel confidence ≥ 70%. |
| 🔄 REVISE | Any checklist item fails, or panel confidence < 70%. |
## Review Loop
1. Planner produces v1 documents
2. Plan Reviewer reviews → REVISE with findings
3. Planner revises → v2 documents
4. Plan Reviewer reviews → APPROVED
5. User gives GO
6. Pipeline proceeds
Max 3 iterations recommended.
@@ -0,0 +1,460 @@
---
name: playwright-e2e
description: Set up standardized Playwright E2E test infrastructure for Next.js + Spring Boot projects. Creates 3-project config (setup/authenticated/unauthenticated), auth flow, Docker test environment, accessibility tests, and seed data. Use when asked to set up Playwright tests, create E2E test infrastructure, add Playwright to a project, or create an integration test harness.
---
# Playwright E2E Test Infrastructure
## When to use
- Setting up Playwright E2E tests for a Next.js + backend project
- Creating test infrastructure from scratch
- Adding authentication-aware E2E testing
- Setting up accessibility testing with axe-core
- Triggers: "set up Playwright tests", "create E2E test infrastructure", "add Playwright to this project", "E2E test suite", "create integration test harness"
## When NOT to use
- Unit testing (use Jest/Vitest instead)
- API-only testing without a frontend (use Postman/REST client)
- Projects without a web frontend
- Adding individual test files to an existing Playwright setup (just write the test directly)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `PROJECT_DIR` | Current workspace | `/Users/pplate/git/personal/inspectflow` |
| `FRONTEND_DIR` | Relative path to frontend | `frontend/` |
| `BASE_URL` | Dev server URL | `http://localhost:3000` |
| `API_URL` | Backend URL | `http://localhost:8080` |
| `LOGIN_EMAIL` | Test user email | `admin@test.de` |
| `LOGIN_PASSWORD` | Test user password | `test123` |
## Expected Output
- `playwright.config.ts` (3-project architecture)
- `e2e/auth.setup.ts`
- `e2e/auth-flow.unauth.spec.ts`
- `e2e/crud-flow.spec.ts` (template)
- `e2e/navigation.spec.ts` (template)
- `e2e/accessibility.spec.ts`
- `docker-compose.test.yml`
- `scripts/seed.sql`
- Updated `package.json` scripts
- Updated `.gitignore`
---
## Workflow
### Step 1: Install dependencies
```bash
cd <FRONTEND_DIR>
pnpm add -D @playwright/test @axe-core/playwright
npx playwright install chromium
```
### Step 2: Create `playwright.config.ts`
Place in `<FRONTEND_DIR>/playwright.config.ts`:
```typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [['html'], ['list']],
use: {
baseURL: process.env.BASE_URL || '<BASE_URL>',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
{
name: 'authenticated',
use: {
...devices['Desktop Chrome'],
storageState: '.auth/admin.json',
},
dependencies: ['setup'],
testIgnore: /.*\.unauth\.spec\.ts/,
},
{
name: 'unauthenticated',
use: { ...devices['Desktop Chrome'] },
testMatch: /.*\.unauth\.spec\.ts/,
},
],
});
```
**Key architecture:**
- `setup` project runs `auth.setup.ts` first — logs in once, saves session
- `authenticated` project reuses saved `storageState` — no repeated logins
- `unauthenticated` project has no auth state — tests public pages and login flows
### Step 3: Create `e2e/auth.setup.ts`
```typescript
import { test as setup, expect } from '@playwright/test';
const authFile = '.auth/admin.json';
setup('authenticate', async ({ page }) => {
const email = process.env.TEST_EMAIL || '<LOGIN_EMAIL>';
const password = process.env.TEST_PASSWORD || '<LOGIN_PASSWORD>';
await page.goto('/login');
await page.getByLabel('E-Mail').fill(email);
await page.getByLabel('Passwort').fill(password);
await page.getByRole('button', { name: /anmelden|login|sign in/i }).click();
// Wait for successful redirect to dashboard
await page.waitForURL('**/dashboard');
await expect(page.locator('body')).not.toContainText('Login');
// Save authentication state
await page.context().storageState({ path: authFile });
});
```
### Step 4: Create `docker-compose.test.yml`
Place in `<PROJECT_DIR>/docker-compose.test.yml`:
```yaml
services:
test-db:
image: postgres:17-alpine
environment:
POSTGRES_DB: testdb
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- "5433:5432"
volumes:
- ./scripts/seed.sql:/docker-entrypoint-initdb.d/01-seed.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U test -d testdb"]
interval: 5s
timeout: 5s
retries: 5
backend:
build:
context: ./backend
dockerfile: Dockerfile
environment:
SPRING_PROFILES_ACTIVE: test
SPRING_DATASOURCE_URL: jdbc:postgresql://test-db:5432/testdb
SPRING_DATASOURCE_USERNAME: test
SPRING_DATASOURCE_PASSWORD: test
JWT_SECRET: test-secret-key-for-e2e-testing-only
ports:
- "8080:8080"
depends_on:
test-db:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 10s
timeout: 5s
retries: 10
```
### Step 5: Create `scripts/seed.sql`
```sql
-- E2E Test Seed Data
-- Password "test123" as BCrypt hash
-- Verify with: echo -n "test123" | htpasswd -bnBC 10 "" - | cut -d: -f2
INSERT INTO users (email, password_hash, name, role, active)
VALUES (
'<LOGIN_EMAIL>',
'$2a$10$/FgU1KyveJ7MaQ7Xv4kxD.5EIQUHujJfZI4K2E1H7pS6parMHJpeG',
'Test Admin',
'ADMIN',
true
) ON CONFLICT (email) DO NOTHING;
-- Sample data (adapt to your schema)
-- INSERT INTO companies (name, created_by) VALUES ('Test GmbH', 1);
```
⚠️ **CRITICAL**: The BCrypt hash `$2a$10$/FgU1KyveJ7MaQ7Xv4kxD.5EIQUHujJfZI4K2E1H7pS6parMHJpeG` is for the password `test123`. If you change the password, regenerate the hash. This was the #1 source of broken tests in CannaManage.
### Step 6: Create test file templates
#### `e2e/auth-flow.unauth.spec.ts`
```typescript
import { test, expect } from '@playwright/test';
test.describe('Authentication Flow', () => {
test('login page loads correctly', async ({ page }) => {
await page.goto('/login');
await expect(page.getByRole('heading', { name: /anmelden|login/i })).toBeVisible();
await expect(page.getByLabel('E-Mail')).toBeVisible();
await expect(page.getByLabel('Passwort')).toBeVisible();
});
test('shows validation errors for empty form', async ({ page }) => {
await page.goto('/login');
await page.getByRole('button', { name: /anmelden|login|sign in/i }).click();
// Expect validation messages
await expect(page.locator('text=/required|pflichtfeld|eingeben/i')).toBeVisible();
});
test('redirects unauthenticated users to login', async ({ page }) => {
await page.goto('/dashboard');
await page.waitForURL('**/login**');
});
test('registration page loads', async ({ page }) => {
await page.goto('/register');
await expect(page.getByRole('heading', { name: /registr/i })).toBeVisible();
});
});
```
#### `e2e/crud-flow.spec.ts`
```typescript
import { test, expect } from '@playwright/test';
test.describe('CRUD Operations', () => {
test('can navigate to list page', async ({ page }) => {
await page.goto('/dashboard');
// Adapt: click sidebar link to your main entity
// await page.getByRole('link', { name: 'Companies' }).click();
// await expect(page.getByRole('heading', { name: 'Companies' })).toBeVisible();
});
test('can create a new item', async ({ page }) => {
// Adapt: navigate to creation form
// await page.goto('/companies/new');
// await page.getByLabel('Name').fill('Test Company');
// await page.getByRole('button', { name: /erstellen|create|save/i }).click();
// await expect(page.locator('text=/erfolgreich|created|success/i')).toBeVisible();
});
test('can edit an existing item', async ({ page }) => {
// Adapt: navigate to edit form
// await page.goto('/companies');
// await page.getByRole('row').first().getByRole('link', { name: /edit|bearbeiten/i }).click();
// await page.getByLabel('Name').fill('Updated Company');
// await page.getByRole('button', { name: /speichern|save|update/i }).click();
// await expect(page.locator('text=/aktualisiert|updated|success/i')).toBeVisible();
});
test('can delete an item', async ({ page }) => {
// Adapt: delete flow with confirmation dialog
// await page.goto('/companies');
// await page.getByRole('row').first().getByRole('button', { name: /löschen|delete/i }).click();
// await page.getByRole('dialog').getByRole('button', { name: /bestätigen|confirm|delete/i }).click();
// await expect(page.locator('text=/gelöscht|deleted|success/i')).toBeVisible();
});
});
```
#### `e2e/navigation.spec.ts`
```typescript
import { test, expect } from '@playwright/test';
test.describe('Navigation', () => {
test('sidebar navigation works', async ({ page }) => {
await page.goto('/dashboard');
// Adapt: check your sidebar links exist
const sidebar = page.locator('[data-sidebar]');
await expect(sidebar).toBeVisible();
});
test('breadcrumbs display correctly', async ({ page }) => {
await page.goto('/dashboard');
// Adapt: verify breadcrumb trail
// await expect(page.locator('nav[aria-label="breadcrumb"]')).toBeVisible();
});
test('mobile menu toggle works', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/dashboard');
// Adapt: check mobile menu behavior
// await page.getByRole('button', { name: /menu/i }).click();
// await expect(page.locator('[data-sidebar]')).toBeVisible();
});
});
```
#### `e2e/accessibility.spec.ts`
```typescript
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
const pages = [
{ name: 'Dashboard', path: '/dashboard' },
// Add all pages to scan:
// { name: 'Companies', path: '/companies' },
// { name: 'New Company', path: '/companies/new' },
];
test.describe('Accessibility', () => {
for (const { name, path } of pages) {
test(`${name} has no accessibility violations`, async ({ page }) => {
await page.goto(path);
await page.waitForLoadState('networkidle');
const results = await new AxeBuilder({ page }).analyze();
// Log violations for debugging
if (results.violations.length > 0) {
console.log(`Accessibility violations on ${name}:`);
results.violations.forEach((v) => {
console.log(` [${v.impact}] ${v.id}: ${v.description}`);
v.nodes.forEach((n) => console.log(` ${n.html}`));
});
}
expect(results.violations).toEqual([]);
});
}
});
```
### Step 7: Add `package.json` scripts
Add to `<FRONTEND_DIR>/package.json` scripts section:
```json
{
"scripts": {
"e2e": "playwright test",
"e2e:ui": "playwright test --ui",
"e2e:headed": "playwright test --headed",
"e2e:report": "playwright show-report"
}
}
```
### Step 8: Update `.gitignore`
Append to `<FRONTEND_DIR>/.gitignore`:
```
# Playwright
.auth/
playwright-report/
test-results/
```
---
## Lessons Learned & Gotchas
### 1. BCrypt hash MUST match the password
The #1 cause of broken E2E suites. If `seed.sql` has a hash that doesn't match the password in `auth.setup.ts`, all authenticated tests fail silently (login form rejects credentials).
**Verify with:**
```bash
echo -n "test123" | htpasswd -bnBC 10 "" - | cut -d: -f2
```
### 2. waitForURL — use globs, not broad regex
```typescript
// ❌ BAD — matches too broadly, causes flaky tests
await page.waitForURL(/dashboard|\//)
// ✅ GOOD — specific glob pattern
await page.waitForURL('**/dashboard')
```
### 3. shadcn/ui selectors
Don't use generic CSS class selectors for shadcn components. They use dynamic Tailwind classes.
```typescript
// ❌ BAD
page.locator('.sidebar')
// ✅ GOOD
page.locator('[data-sidebar]') // sidebar
page.locator('[role="dialog"]') // modals/dialogs
page.getByRole('button', { name: 'Save' }) // buttons
page.getByLabel('Email') // form fields
```
### 4. Console error filtering
Tests fail on unexpected console errors. Filter known/expected ones:
```typescript
const errors: string[] = [];
page.on('console', msg => {
if (msg.type() === 'error' && !msg.text().includes('expected-error-pattern')) {
errors.push(msg.text());
}
});
// ... do test actions ...
expect(errors).toEqual([]);
```
### 5. Auth state caching = 10x speed
The `setup` project runs ONCE per test run. All `authenticated` tests reuse the saved `.auth/admin.json` session cookie. Never log in per-test unless testing auth specifically.
### 6. Accessibility scanning pattern
```typescript
import AxeBuilder from '@axe-core/playwright';
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
```
Run on every page. Add new pages to the `pages` array in `accessibility.spec.ts`.
### 7. Visual regression (optional, add when ready)
```typescript
await expect(page).toHaveScreenshot('page-name.png', { maxDiffPixels: 100 });
```
First run creates baseline screenshots. Subsequent runs compare. Commit screenshots to git.
### 8. Docker test environment
Backend should have a `test` Spring profile that:
- Uses the test PostgreSQL (port 5433 to avoid conflicts)
- Runs Flyway migrations + seed on startup
- Has shorter JWT expiry for faster test cycles
- Disables rate limiting and email sending
---
## Troubleshooting
| Problem | Cause | Fix |
|---------|-------|-----|
| All auth tests fail | Wrong BCrypt hash in seed.sql | Regenerate hash for your password |
| `waitForURL` times out | URL doesn't match pattern | Use `page.url()` to print actual URL, adjust pattern |
| Tests pass locally, fail in CI | Missing `npx playwright install` | Add to CI setup step |
| `storageState` file not found | `.auth/` directory doesn't exist | Create `.auth/` dir or let setup create it |
| Flaky navigation tests | Page not fully loaded | Add `await page.waitForLoadState('networkidle')` |
| axe violations on shadcn | Missing aria labels | Add `aria-label` to interactive elements |
@@ -0,0 +1,121 @@
---
name: sprint-report
description: Generate sprint status report from Jira data.
---
# Skill: sprint-report
Generate sprint status report from Jira data.
## Invoked by
🎫 JiraOps mode (or 🪃 Orchestrator)
## Required Inputs
| Input | Source | Example |
|-------|--------|---------|
| `PROJECT_KEY` | Jira project key | `PROJECT` |
| `SPRINT_ID` | Sprint ID (optional — auto-detected) | `1234` |
## Output
Markdown report: `docs/sprint-reports/sprint-<sprint_name>-<date>.md`
## Steps
### 1. Get active sprint
```python
boards = get_agile_boards(project_key=PROJECT_KEY)
sprints = get_sprints_from_board(board_id=boards[0]["id"], states="active")
sprint = sprints[0]
```
### 2. Get sprint tickets
```python
tickets = get_tickets_from_sprint(sprint_id=sprint["id"])
```
### 3. Categorize by status
| Category | Statuses |
|----------|----------|
| To Do | `Open`, `Backlog`, `To Do` |
| In Progress | `In Progress`, `In Development` |
| In Review | `In Review`, `Code Review` |
| Done | `Done`, `Accepted`, `Closed` |
### 4. Calculate metrics
```python
total = len(tickets)
done = len([t for t in tickets if t["status"] in DONE_STATUSES])
completion_pct = round(done / total * 100) if total > 0 else 0
```
### 5. Generate report
```markdown
# Sprint Report: <sprint_name>
**Date:** <today>
**Sprint:** <sprint_name>
**Period:** <start> — <end>
**Project:** <PROJECT_KEY>
---
## Overview
| Metric | Value |
|--------|-------|
| Total tickets | <total> |
| Done | <done> (<pct>%) |
| In Progress | <wip> |
| Open | <todo> |
## Progress
```
[████████████░░░░░░░░] 60% (<done>/<total>)
```
## By Status
### ✅ Done (<done>)
| Ticket | Type | Summary | Assignee |
|--------|------|---------|----------|
| <key> | Story | <summary> | <name> |
### 🔄 In Progress (<wip>)
| Ticket | Type | Summary | Assignee |
|--------|------|---------|----------|
### ⏳ Open (<todo>)
| Ticket | Type | Summary | Assignee |
|--------|------|---------|----------|
## By Assignee
| Assignee | Total | Done | In Progress | Open |
|----------|-------|------|-------------|------|
## Blockers / Risks
| Ticket | Description | Since | Impact |
|--------|-------------|-------|--------|
```
### 6. Store in BigMind
```python
memory_store_fact(
category="codebase",
fact=f"Sprint report for {sprint_name}: {done}/{total} done ({pct}%)"
)
```
@@ -0,0 +1,107 @@
---
name: switch-worktree
description: Switch VS Code to an existing git worktree. Lists worktrees, replaces the current window (code -r), announces BigMind focus, and restores session context. Use when asked to switch worktree, open another ticket, change to a different branch/ticket, or activate a worktree.
---
# Switch Worktree
## When to use
- User wants to switch to a different ticket worktree
- User says "switch to PROJECT-XXX", "open worktree for ...", "go to ticket ..."
- User wants to see available worktrees and pick one
## When NOT to use
- User wants to **create** a new worktree → use `create-worktree` skill instead
- User wants to delete/remove a worktree
- User just wants to see git history (no switch needed)
## Inputs
| Input | Required | Source | Example |
|-------|----------|--------|---------|
| `TICKET_KEY` | Optional | User or interactive selection | `PROJECT-123` |
If no ticket key is provided, list all worktrees and let the user pick.
## Workflow
### 1. List available worktrees
```bash
git -C <your-repo-path> worktree list
```
Parse output to show available worktrees with their branches.
### 2. Match or select target
If `TICKET_KEY` provided:
- Look for a worktree path containing the ticket key
- If not found, report error and show available worktrees
If no `TICKET_KEY`:
- Present the list and ask the user to pick
### 3. Show worktree status before switching
```bash
cd <target_worktree_path>
git branch --show-current
git status --short
git log --oneline -3
```
Report: branch name, uncommitted changes (if any), last 3 commits.
### 4. Switch VS Code window
```bash
code -r <target_worktree_path>
```
This replaces the current VS Code window with the target worktree.
**Important:** After this command, the current Roo session ends because the workspace changes. The next Roo session will start in the new worktree.
### 5. Update BigMind focus
Before executing `code -r`, announce the switch:
```python
memory_store_fact(
category="codebase",
fact=f"Switched worktree to {TICKET_KEY} at {target_path}, branch {branch_name}"
)
memory_announce_focus(
session_id=SESSION_ID,
description=f"Switching to {TICKET_KEY} worktree",
files=[target_path],
ide_hint="Roo"
)
```
### 6. Context recovery hint
After switching, the next session should:
1. Run `memory_search_facts("<TICKET_KEY>")` to find prior work
2. Run `memory_search_chunks("<TICKET_KEY>")` for detailed context
3. Check `docs/<MODULE>/<TICKET_KEY>/` for existing documentation
This happens automatically via the BigMind session ritual.
## Error Handling
| Error | Resolution |
|-------|------------|
| No worktrees found | Only the main repo exists — suggest `create-worktree` |
| Ticket worktree not found | Show available worktrees, ask user to pick or create |
| Uncommitted changes in current worktree | Warn user before switching — suggest commit or stash |
| `code` CLI not available | Run `Shell Command: Install 'code' command in PATH` from VS Code |
## Notes
- `code -r` replaces the current window — the Roo session will end after this
- The new window starts fresh — BigMind provides continuity across the switch
- If the user has uncommitted changes, always warn before switching
@@ -0,0 +1,140 @@
---
name: visual-verify
description: Verify a frontend page visually using Playwright. Takes screenshots (dark/light mode), extracts visible text, checks element positioning and responsive layout. Use when asked to verify a page, check how it looks, take a screenshot, or after building a new UI component.
---
# Visual Verify
## When to use
- After creating or modifying a frontend page/component
- When asked "how does it look", "verify the page", "take a screenshot"
- To check dark/light mode rendering
- To verify text content (i18n) renders correctly
- To check centering, alignment, and responsive layout
## When NOT to use
- For unit tests or API testing (use test runners instead)
- For full E2E test suites (use Playwright test framework directly)
- When the dev server is not running
## Prerequisites
- Playwright installed in the frontend project: `pnpm add -D playwright`
- Chromium browser installed: `npx playwright install chromium`
- Dev server running (usually `pnpm dev` on localhost:3000)
## Inputs
| Input | Required | Default | Example |
|-------|----------|---------|---------|
| URL | Yes | — | `http://localhost:3000/login` |
| Checks | No | all | `text`, `screenshot`, `position`, `responsive`, `interaction` |
| Theme | No | both | `dark`, `light`, `both` |
| Viewport | No | 1280x720 | `375x667` (mobile) |
## Workflow
### 1. Launch browser and navigate
```javascript
const { chromium } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
await page.goto(URL);
await page.waitForTimeout(2000); // Wait for hydration
```
### 2. Extract visible text
```javascript
const text = await page.locator('body').innerText();
// Report: verify all expected text is present (i18n keys rendered)
```
### 3. Check element positioning
```javascript
// Verify centering of a key element
const box = await page.locator('SELECTOR').boundingBox();
const vp = page.viewportSize();
const centerX = Math.round(box.x + box.width / 2);
const centerY = Math.round(box.y + box.height / 2);
// Report: distance from viewport center
```
### 4. Take screenshots
```javascript
// Dark mode (default)
await page.screenshot({ path: '/tmp/verify-dark.png', fullPage: true });
// Light mode
await page.evaluate(() => {
document.documentElement.classList.remove('dark');
document.documentElement.style.colorScheme = 'light';
});
await page.waitForTimeout(500);
await page.screenshot({ path: '/tmp/verify-light.png', fullPage: true });
```
### 5. Responsive check (optional)
```javascript
// Mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await page.waitForTimeout(500);
await page.screenshot({ path: '/tmp/verify-mobile.png', fullPage: true });
// Tablet
await page.setViewportSize({ width: 768, height: 1024 });
await page.waitForTimeout(500);
await page.screenshot({ path: '/tmp/verify-tablet.png', fullPage: true });
```
### 6. Interaction check (optional)
```javascript
// Click a button and verify outcome
await page.locator('button[type="submit"]').click();
await page.waitForTimeout(1000);
const errorText = await page.locator('body').innerText();
// Report: what changed after interaction
```
### 7. Report findings
Produce a summary:
```
=== Visual Verification: <URL> ===
✅ Text renders: <key phrases found>
✅ Horizontally centered (X: 640/640)
⚠️ Vertically offset (Y: 414 vs 360) — acceptable, content above pushes down
✅ Dark mode: screenshot saved
✅ Light mode: screenshot saved
⚠️ Mobile: form overflows at 375px width
```
### 8. Clean up
```javascript
await browser.close();
```
## Output
- Console report with pass/fail per check
- Screenshots at `/tmp/verify-*.png` (dark, light, mobile, tablet)
- Actionable findings if issues detected
## Troubleshooting
| Issue | Resolution |
|-------|-----------|
| Page blank / no text | Increase `waitForTimeout` — hydration may be slow |
| Cannot find module 'playwright' | Run `pnpm add -D playwright` in the frontend project |
| Browser not found | Run `npx playwright install chromium` |
| Connection refused | Ensure dev server is running on the expected port |
| Dark mode not toggling | Check if theme uses `class="dark"` on `<html>` or `data-theme` attribute |