Manages Etendo development workflow conventions. ALWAYS use this skill when working in any Etendo repository — repos under the etendosoftware GitHub org, modules with com.etendo* or com.smf* Java packages, projects whose gradle.properties references etendo dependencies, or any directory inside an Etendo workspace (modules/, modules_core/, etc.). Covers git commits, branch naming, PR titles, Jira and GitHub issue creation, and bug tracking. Trigger on ANY git operation (commit, branch, push, PR) performed in Etendo context, when creating or discussing tickets/bugs/stories/tasks, when a bug is detected during code analysis, when the user asks to commit or push changes, or when reviewing PR feedback. If you are unsure whether the current project is Etendo-related, check for gradle.properties with bbdd.* keys, an etendo-core dependency, or a modules/ directory — if any are present, use this skill for all git operations.
npx claudepluginhub etendosoftware/etendo_claude_marketplace --plugin etendo-workflow-managerThis skill uses the workspace's default tool permissions.
Manages the complete Etendo development workflow: issue creation (Jira + GitHub), branch naming, and commit formatting, all following the ETP project conventions and Git Police rules.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Manages the complete Etendo development workflow: issue creation (Jira + GitHub), branch naming, and commit formatting, all following the ETP project conventions and Git Police rules.
/memory) so you don't need to ask again in future sessions. Retrieve issue type IDs (Bug, Story, Task) by querying the Jira API when creating the issue.etendosoftwareIn Etendo, code is organized into bundles and modules:
com.etendoerp.copilot.extensions) that groups several related modules.com.etendoerp.copilot, com.etendoerp.copilot.toolpack) where the actual code changes happen.When a bug is reported, the GitHub issue is created in the bundle repo, even though the actual changes are made in one or more of its modules.
Branches must follow these exact patterns, validated by Git Police:
| Pattern | Example | Usage |
|---|---|---|
feature/XYZ-1234 | feature/ETP-3400 | Standard feature |
feature/XYZ-1234-Y<yy> | feature/ETP-3400-Y26 | Backport to release year |
| Pattern | Example | Usage |
|---|---|---|
hotfix/XYZ-1234 | hotfix/ETP-3400 | Hotfix without GitHub issue |
hotfix/#N-XYZ-1234 | hotfix/#42-ETP-3400 | Hotfix with GitHub issue (most common) |
hotfix/#N-XYZ-1234-Y<yy> | hotfix/#42-ETP-3400-Y26 | Backport hotfix |
| Pattern | Example | Usage |
|---|---|---|
epic/XYZ-1234 | epic/ETP-3400 | Standard epic |
epic/XYZ-1234-Y<yy> | epic/ETP-3400-Y26 | Backport epic |
XYZ = Jira project code (2-4 uppercase letters, e.g., ETP)1234 = Jira issue number (1-4 digits)#N = GitHub issue number in the bundle (1-6 digits)Y<yy> = backport year (2 digits, e.g., Y26 for 2026)Branches are created in the modules where changes are made, not in the bundle.
Commit messages are validated by Git Police. First line maximum 80 characters.
Feature ETP-1234: Brief change description
Feature ABC-123: (with a space after the colon).-m for the body.Commits on hotfix branches always use the Issue format, both in commits and PR titles:
Issue #42: Brief fix description
Issue #<number>: followed by a descriptive message (max 80 chars).ETP-3400).#N is the GitHub issue number of the bundle.Epic ETP-1234: Brief description
Epic ABC-123: followed by a descriptive message.# Feature commit
git commit -m "Feature ETP-3400: Add OAuth2 support for API auth"
# Hotfix commit (always Issue format, requires Jira ID in second message)
git commit -m "Issue #42: Fix NPE on session expiry" -m "ETP-3400"
# Hotfix PR title (same format)
# Issue #42: Fix NPE on session expiry
project = ETP AND issuetype = Epic AND summary ~ "Etendo Maintenance" AND status != Done ORDER BY created DESC.bug label.project = ETP AND issuetype = Epic AND status != Done ORDER BY created DESC.# Error's description
[Clear description of the error, what fails and in what context]
# Steps to reproduce the error
### Required Configurations (if necessary)
1. [Step 1]
2. [Step 2]
3. [Step 3]
# Expected behavior
[What should happen instead of the error]
# Affected Version
Version number: [affected version]
# Solution Design (optional)
[Technical solution proposal if known]
# Other test cases
**Given:** [initial condition]
**When:** [action executed]
**Then:** [expected result]
Issue
[link to GitHub issue — filled in after creating the GitHub issue]
# Issue Description
* [Functional description with bullets of what is needed]
# Solution Design
* [Detailed technical design]
* [May include subsections: DB, Backend/API, Frontend/UI, etc.]
Analyze $ARGUMENTS and/or the conversation context to determine:
atlassianUserInfo tool to get the current user's accountId, then pass it as assignee_account_id when creating the Jira issue. If the user explicitly names a different assignee, use lookupJiraAccountId to find that person instead.Ask the user which bundle (repository in the etendosoftware organization) to create the GitHub issue in. Remember that the issue goes in the bundle, not in individual modules.
Show a summary before creating:
Project: ETP
Type: Bug
Epic: Etendo Maintenance Y26Q1
Summary: Fix login error when session expires
Priority: Medium
Assignee: [current user name — auto-assigned]
GH Bundle: etendosoftware/com.etendoerp.copilot.extensions (bugs only)
For Bugs (order matters):
createJiraIssue). Get the key (e.g., ETP-3400).[ETP-3400] same summarybugIssue
[link to GitHub issue]
For Story/Task:
createJiraIssue.Show the created issue key with a link, and if it's a bug, also the GitHub issue link. Additionally, indicate the branch name to use for working in the modules:
hotfix/#N-JIRA-CODE (e.g., if the GitHub issue is #42 and the Jira key is ETP-3400 → hotfix/#42-ETP-3400)feature/JIRA-CODE (e.g., feature/ETP-3400)epic/JIRA-CODE (e.g., epic/ETP-3400)And the commit format they should use:
Issue #42: Description with a second -m "ETP-3400" (always Issue format)Feature ETP-3400: ...Epic ETP-3400: ...When the user asks to make a commit or create a branch, validate that it follows the conventions before executing:
#N.Feature, Hotfix, Epic, or Issue).ETP-3400).echo -n "Feature ETP-3400: Change description" | wc -c
If the result is greater than 80, shorten the description before committing. Never assume the message is short enough — always measure.Issue type commit, ensure the second message contains the Jira ID.When a bug is resolved, look for a way to add a test that covers that case. A bug fixed without a test is a bug that can reappear. The goal is that if someone introduces the same regression in the future, the test fails and catches it before it reaches production.
Co-Authored-By in commit messages. Git Police may reject them and it's not part of Etendo conventions.open <url>) so they can make the change manually, and inform them what action needs to be completed (e.g., "Couldn't create the issue due to rate limit. I've opened Jira in your browser — create it with this data: ...").After pushing commits, the Auto Reviewer GitHub Actions workflow runs automatically and the bot (etendobot) posts review comments on the PR. There are two types:
**Suggestion**.⚠️ Blocking Issue.gh api graphql -f query='
{
repository(owner: "etendosoftware", name: "REPO_NAME") {
pullRequest(number: PR_NUMBER) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 1) {
nodes { body path line databaseId }
}
}
}
}
}
}'
Parse the result to separate blocking threads (⚠️ Blocking Issue in body) from suggestions.
For each non-blocking thread ID (PRRT_xxx):
gh api graphql -f query="mutation {
resolveReviewThread(input: {threadId: \"PRRT_xxx\"}) {
thread { id isResolved }
}
}"
The bot has limited context. It reviews the diff without understanding the full flow of the code. For each blocking issue:
If the concern doesn't hold up against the actual code → mark as false positive. If it's a real issue → fix it before re-running the reviewer.
Reply /false-positive to the original comment of the thread. Use the databaseId from Step 1:
gh api repos/etendosoftware/REPO_NAME/pulls/PR_NUMBER/comments/COMMENT_DATABASE_ID/replies \
-X POST -f body="/false-positive"
After fixing real blocking issues or marking false positives, re-trigger the bot:
# Find the last Auto Reviewer run ID
gh run list --repo etendosoftware/REPO_NAME --branch BRANCH_NAME --limit 5
# Re-run it
gh run rerun RUN_ID --repo etendosoftware/REPO_NAME
When the SonarQube quality gate fails on a PR, use the /etendo:sonar skill to:
sonar-scanner locally in PR mode to reproduce the same analysis as CISee the etendo-sonar skill for full details on running the scanner, querying results, and auto-fixing common issues. Always run Sonar analysis before pushing to catch issues early.
When tests fail on a PR's Jenkins build, follow this workflow to identify and fix the root cause.
This workflow requires the Jenkins MCP server. If not installed, run:
claude mcp add --transport stdio --scope user jenkins -- uvx mcp-jenkins \
--jenkins-url=<JENKINS_URL> \
--jenkins-username=<USERNAME> \
--jenkins-password=<PASSWORD>
If the command doesn't work, configure it manually by editing ~/.claude.json and adding the following entry inside mcpServers:
"jenkins": {
"type": "stdio",
"command": "uvx",
"args": [
"mcp-jenkins",
"--jenkins-url=<JENKINS_URL>",
"--jenkins-username=<USERNAME>",
"--jenkins-password=<PASSWORD>"
]
}
Then restart Claude Code for the MCP to load.
gh pr checks <PR_NUMBER> --repo etendosoftware/<REPO_NAME>
Identify the Module Tests check that shows fail. Note the Jenkins build URL (e.g., https://jenkins2.etendo.cloud/job/copilot-module-tests/4726/). Extract the job name and build number.
Use the Jenkins MCP to fetch the build console output:
get_build_console_output(fullname="<job-name>", number=<build-number>)
The output can be very large. Search for key patterns to find test failures:
FAILED — individual test failuresBUILD FAILURE — overall build failureTests run.*Failures — test summary linesDelegate the analysis to a general-purpose subagent to keep the main context clean. Pass it:
Read the failing test methods and any shared setup/teardown (
@Before,@After,setUp(),tearDown()). Identify the root cause of each failure. Return a diagnosis with: (1) the root cause, (2) why only these tests are affected, and (3) the exact fix to apply.
The subagent must return a structured diagnosis before any fix is applied:
## Diagnosis
### Failing tests
- `TestClass > methodName`
### Root cause
[What exactly triggers the exception and why]
### Why only these tests
[What distinguishes them from passing tests]
### Proposed fix
[Exact code change with file path and line numbers]
Review the diagnosis before applying the fix. If it looks correct, instruct the subagent (or apply yourself) the change.
Apply the fix to the relevant source file. Report to the user: