From 9e15a83b8aeb9eec2cb7391799f793e0c9d66f8b Mon Sep 17 00:00:00 2001 From: Andrei Gasparian Date: Thu, 19 Mar 2026 16:24:27 +0100 Subject: [PATCH 1/3] Add workflow skills: create-branch, create-pr, make-yt-issue Extract branch creation, PR workflow, and YouTrack issue creation from CLAUDE.md prose into dedicated invocable skills. Simplify CLAUDE.md "After Completing Work" steps to reference the new skills. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/create-branch/SKILL.md | 48 ++++++++++++ .claude/skills/create-branch/evals/evals.json | 38 +++++++++ .claude/skills/create-pr/SKILL.md | 78 +++++++++++++++++++ .claude/skills/create-pr/evals/evals.json | 38 +++++++++ .claude/skills/make-yt-issue/SKILL.md | 52 +++++++++++++ .claude/skills/make-yt-issue/evals/evals.json | 35 +++++++++ CLAUDE.md | 46 ++--------- 7 files changed, 295 insertions(+), 40 deletions(-) create mode 100644 .claude/skills/create-branch/SKILL.md create mode 100644 .claude/skills/create-branch/evals/evals.json create mode 100644 .claude/skills/create-pr/SKILL.md create mode 100644 .claude/skills/create-pr/evals/evals.json create mode 100644 .claude/skills/make-yt-issue/SKILL.md create mode 100644 .claude/skills/make-yt-issue/evals/evals.json diff --git a/.claude/skills/create-branch/SKILL.md b/.claude/skills/create-branch/SKILL.md new file mode 100644 index 00000000..bc0f918a --- /dev/null +++ b/.claude/skills/create-branch/SKILL.md @@ -0,0 +1,48 @@ +--- +name: create-branch +description: Create a feature branch following project naming conventions. Use when starting work on a ticket, after understanding the scope, or when the agent needs to branch off main for new work. +--- + +# Create Branch + +Create a feature branch following the `/` +convention used in this repository. + +## Steps + +### 1. Detect the user's nickname + +Query existing remote branches to find the most frequent author prefix: + +```bash +git branch -r | sed -nE 's|^ *origin/([^/]+)/.*|\1|p' | grep -vE '^(dependabot|HEAD|revert-)' | sort | uniq -c | sort -rn +``` + +Pick the top result. If ambiguous or no branches exist, ask the user. + +### 2. Derive a descriptive branch name + +Combine the ticket ID (if available) and a short slug describing the change: + +- Use lowercase kebab-case: `fix-auth-timeout`, `add-mcp-tool-list` +- Keep it under 50 characters +- If a YouTrack ticket is known (e.g., `DBA-123`), prefer including it: + `/DBA-123-fix-auth-timeout` + +### 3. Ensure a clean starting point + +- Fetch latest: `git fetch origin` +- If the working tree has uncommitted changes, warn the user and ask whether + to stash or proceed. +- Branch from `main` (or the base branch the user specifies): + `git checkout -b / origin/main` + +### 4. Confirm + +Report the created branch name to the user. + +## Guardrails + +- Never create branches directly on `main` — always branch _from_ main. +- Never silently discard uncommitted changes. +- If the user is already on a feature branch, ask before switching. diff --git a/.claude/skills/create-branch/evals/evals.json b/.claude/skills/create-branch/evals/evals.json new file mode 100644 index 00000000..d1fee2cc --- /dev/null +++ b/.claude/skills/create-branch/evals/evals.json @@ -0,0 +1,38 @@ +{ + "skill_name": "create-branch", + "evals": [ + { + "id": 1, + "prompt": "Create a branch for ticket DBA-150 about fixing the status command output.", + "expected_output": "Agent detects nickname from remotes, creates a branch like /DBA-150-fix-status-output from origin/main.", + "assertions": [ + "Agent runs the nickname detection command against remote branches", + "Agent fetches from origin before creating the branch", + "Branch name follows `/` pattern", + "Branch is created from origin/main, not from the current HEAD of an unrelated branch", + "Agent reports the created branch name to the user" + ] + }, + { + "id": 2, + "prompt": "I need a new branch for some exploratory work, no ticket yet.", + "expected_output": "Agent creates a branch with a descriptive name without a ticket prefix.", + "assertions": [ + "Agent detects the nickname from remote branches", + "Agent asks or derives a descriptive slug for the branch", + "Branch name does NOT include a ticket ID since none was provided", + "Agent does NOT require a ticket to proceed" + ] + }, + { + "id": 3, + "prompt": "Create a branch for DBA-200. I have uncommitted changes in my working tree.", + "expected_output": "Agent warns about uncommitted changes and asks user how to proceed before branching.", + "assertions": [ + "Agent detects or warns about uncommitted changes", + "Agent asks the user whether to stash, commit, or abort before switching branches", + "Agent does NOT silently discard uncommitted changes" + ] + } + ] +} diff --git a/.claude/skills/create-pr/SKILL.md b/.claude/skills/create-pr/SKILL.md new file mode 100644 index 00000000..73b3b630 --- /dev/null +++ b/.claude/skills/create-pr/SKILL.md @@ -0,0 +1,78 @@ +--- +name: create-pr +description: Stage, commit, push, and open a GitHub PR following project conventions. Use when code is ready to ship — after tests pass, code review, and architecture review are done. +--- + +# Create PR + +Stage changes, commit, push, and open a GitHub pull request following +project conventions. + +## Steps + +### 1. Verify preconditions + +- Confirm you are NOT on `main`. Abort if so. +- Check `git status` for changes to commit. If nothing to commit, inform + the user and stop. +- Warn (but do not block) if `make check` or `make test-cov-check` have + not been run in this session. + +### 2. Determine the ticket ID + +- Extract from the current branch name if it contains `DBA-`. +- Otherwise ask the user for the ticket ID. +- Prefix every commit message with the ticket ID: `[DBA-123] Description`. + +### 3. Stage and commit + +- Stage relevant files (prefer explicit paths over `git add -A`). +- Commit with `[DBA-XXX] Description of change`. + +### 4. Pause for confirmation + +Present the user with: + +- The branch name and commit(s) that will be pushed. +- A draft PR description following the template below. + +**Wait for explicit user confirmation before proceeding.** + +### 5. Push and create PR + +- Push with `-u` flag: `git push -u origin ` +- Create the PR via `gh pr create` using the template: + +``` +## Summary +<1-3 sentence overview of why this change exists> + +## Changes + +### + +
Files + +- `path/to/file1` +- `path/to/file2` +
+ +### +... + +## Test Plan +- [ ] +``` + +### 6. Report + +Output the PR URL so the user can review it. + +## Guardrails + +- Never push to `main`. +- Never push without explicit user confirmation. +- Never skip the `[DBA-XXX]` commit prefix when a ticket is known. +- Never use `git add -A` or `git add .` — stage specific files. +- If `gh` CLI is not available, show the push command and PR URL for + manual creation. diff --git a/.claude/skills/create-pr/evals/evals.json b/.claude/skills/create-pr/evals/evals.json new file mode 100644 index 00000000..b54aec02 --- /dev/null +++ b/.claude/skills/create-pr/evals/evals.json @@ -0,0 +1,38 @@ +{ + "skill_name": "create-pr", + "evals": [ + { + "id": 1, + "prompt": "Create a PR for the changes on my current branch. The ticket is DBA-180.", + "expected_output": "Agent stages changes, commits with [DBA-180] prefix, presents a draft PR, pauses for confirmation, then pushes and creates the PR.", + "assertions": [ + "Agent commits with a message prefixed by [DBA-180]", + "Agent presents a draft PR description to the user before pushing", + "Agent waits for explicit user confirmation before pushing", + "Agent pushes with the -u flag", + "PR description follows the Summary / Changes / Test Plan template", + "Agent reports the PR URL after creation" + ] + }, + { + "id": 2, + "prompt": "Ship my changes as a PR. I'm on a feature branch but I don't remember the ticket number.", + "expected_output": "Agent tries to extract the ticket ID from the branch name; if not found, asks the user.", + "assertions": [ + "Agent attempts to extract a ticket ID from the current branch name", + "If no ticket ID is found in the branch name, agent asks the user", + "Agent does NOT push without a commit message prefix when a ticket is expected" + ] + }, + { + "id": 3, + "prompt": "Create a PR. I'm currently on the main branch.", + "expected_output": "Agent refuses to push directly to main and suggests creating a feature branch first.", + "assertions": [ + "Agent detects that the current branch is main", + "Agent does NOT push to main", + "Agent suggests creating a feature branch or switching to one" + ] + } + ] +} diff --git a/.claude/skills/make-yt-issue/SKILL.md b/.claude/skills/make-yt-issue/SKILL.md new file mode 100644 index 00000000..ac479f41 --- /dev/null +++ b/.claude/skills/make-yt-issue/SKILL.md @@ -0,0 +1,52 @@ +--- +name: make-yt-issue +description: Create a YouTrack issue for planned work using MCP tools. Use when no ticket exists for the work, when the user asks to create a ticket, or before starting untracked work. +--- + +# Make YouTrack Issue + +Create a YouTrack issue in the DBA project using the YouTrack MCP tools. + +## Steps + +### 1. Gather issue details + +Ask the user for (or propose from conversation context): + +- **Summary**: concise one-line title +- **Description**: what the work involves and why +- **Type**: Bug, Task, Feature, or other applicable type + +### 2. Show the proposed issue + +Present the summary, description, and type to the user. +**Wait for explicit approval before creating.** + +### 3. Create the issue + +Use the `create_issue` MCP tool to create the issue in the DBA project. + +### 4. Report + +Output the issue ID (e.g., `DBA-123`) so the user can reference it. + +### 5. Optionally transition to Develop + +If the user is starting work immediately, move the issue to **Develop** +state using `update_issue` (set the `State` field). + +## Guardrails + +- Never create an issue without explicit user approval of the summary, + description, and type. +- If the YouTrack MCP server is unavailable, inform the user and refer + them to `DEVELOPMENT.md` for setup instructions. +- Default to the `DBA` project unless the user specifies otherwise. + +## What this skill does NOT do + +- It does not manage issue state transitions beyond the initial Develop + move — ongoing state management (Develop → Review) is handled by the + development workflow in CLAUDE.md. +- It does not search or update existing issues — use `get_issue` and + `update_issue` MCP tools directly for that. diff --git a/.claude/skills/make-yt-issue/evals/evals.json b/.claude/skills/make-yt-issue/evals/evals.json new file mode 100644 index 00000000..244b0b36 --- /dev/null +++ b/.claude/skills/make-yt-issue/evals/evals.json @@ -0,0 +1,35 @@ +{ + "skill_name": "make-yt-issue", + "evals": [ + { + "id": 1, + "prompt": "Create a YouTrack ticket for adding a new 'config' CLI command that lets users manage project settings.", + "expected_output": "Agent proposes an issue with summary, description, and type, waits for approval, then creates it via MCP.", + "assertions": [ + "Agent proposes a summary, description, and type before creating", + "Agent waits for explicit user approval before calling create_issue", + "Agent reports the created issue ID (e.g., DBA-XXX) after creation" + ] + }, + { + "id": 2, + "prompt": "I want to start working on something but there's no ticket yet. Can you make one?", + "expected_output": "Agent asks for details to populate the issue, then proposes and creates after approval.", + "assertions": [ + "Agent asks the user for issue details (summary, description, or type)", + "Agent does NOT create an issue without gathering sufficient information", + "Agent presents the proposed issue for approval before creating" + ] + }, + { + "id": 3, + "prompt": "Create a YouTrack issue and start working on it right away.", + "expected_output": "Agent creates the issue after approval and moves it to Develop state.", + "assertions": [ + "Agent waits for approval before creating the issue", + "After creation, agent moves the issue to Develop state using update_issue", + "Agent reports both the issue ID and the state transition" + ] + } + ] +} diff --git a/CLAUDE.md b/CLAUDE.md index dd8f9b65..9646d1c6 100755 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -94,8 +94,7 @@ style issues; do not manually fix formatting. for setup instructions. - If a ticket is provided, read it with the `get_issue` tool to understand the full scope before writing any code. -- If no ticket exists for the work, propose one (show summary, description, and - type) and wait for explicit user approval before creating it. +- If no ticket exists for the work, use the `make-yt-issue` skill to create one. - When starting work on a ticket, move it to **Develop** state using `update_issue` (set `State` field). - After creating a PR, move the ticket to **Review** state and add the @@ -115,42 +114,9 @@ style issues; do not manually fix formatting. findings before proceeding. 5. **Architecture review** — review architecture quality of the changed code. Fix any high-severity issues before proceeding. -6. **Branch** — create a branch following `/`. - Detect the user's nickname from existing remote branches: - ```bash - git branch -r | sed -nE 's|^ *origin/([^/]+)/.*|\1|p' | grep -vE '^(dependabot|HEAD|revert-)' | sort | uniq -c | sort -rn - ``` -7. **Commit** — stage and commit with `[DBA-123] Description of change`. -8. **Pause** — present the user with a summary of what will be pushed and - the draft PR description. Wait for explicit confirmation before - proceeding. -9. **Push & PR** — push with `-u` flag, create PR using the standard - format (see Pull Request Format section). -10. **Update YouTrack** — move the ticket to **Review** state and add +6. **Branch** — use the `create-branch` skill. +7. **Commit & PR** — use the `create-pr` skill (stages, commits, pauses + for confirmation, pushes, and opens the PR). +8. **Update YouTrack** — move the ticket to **Review** state and add a comment with the PR URL. -11. Never commit directly to `main`. - -## Pull Request Format - -Use the following structure for PR descriptions: - -``` -## Summary -<1–3 sentence overview of why this change exists> - -## Changes - -### - -
Files - -- `path/to/file1` -- `path/to/file2` -
- -### -... - -## Test Plan -- [ ] -``` +9. Never commit directly to `main`. From 60f26ee0a78a2101822465bc275f5591b10cdcae Mon Sep 17 00:00:00 2001 From: Andrei Gasparian Date: Thu, 19 Mar 2026 18:53:53 +0100 Subject: [PATCH 2/3] Add update-pr skill, quality gates in create-pr, and commit message guidelines - Add new update-pr skill for fast branch/PR iterations (stage, commit, push) - Add blocking quality gates (make check + make test) to create-pr skill - Add commit message conventions to CLAUDE.md as single source of truth - Remove duplicated commit format rules from individual skills - create-pr now delegates to create-branch when on main instead of aborting Co-Authored-By: Claude Opus 4.6 --- .claude/skills/create-pr/SKILL.md | 34 ++++++++++----- .claude/skills/update-pr/SKILL.md | 52 +++++++++++++++++++++++ .claude/skills/update-pr/evals/evals.json | 37 ++++++++++++++++ CLAUDE.md | 12 +++++- 4 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 .claude/skills/update-pr/SKILL.md create mode 100644 .claude/skills/update-pr/evals/evals.json diff --git a/.claude/skills/create-pr/SKILL.md b/.claude/skills/create-pr/SKILL.md index 73b3b630..d6e12896 100644 --- a/.claude/skills/create-pr/SKILL.md +++ b/.claude/skills/create-pr/SKILL.md @@ -12,24 +12,36 @@ project conventions. ### 1. Verify preconditions -- Confirm you are NOT on `main`. Abort if so. +- Confirm you are NOT on `main`. If on `main`, run the `create-branch` + skill to create a feature branch before continuing. - Check `git status` for changes to commit. If nothing to commit, inform the user and stop. -- Warn (but do not block) if `make check` or `make test-cov-check` have - not been run in this session. +### 2. Run quality gates -### 2. Determine the ticket ID +These are **blocking** — do not commit until both pass. + +1. **`make check`** (ruff + mypy) + - Run `make check`. + - If ruff fails, auto-fix with `uv run ruff check --fix src/databao_cli && uv run ruff format src/databao_cli`, then re-run `make check`. + - If mypy fails after ruff is clean, stop and fix the type errors before continuing. +2. **`make test`** (pytest) + - Run `make test`. + - If tests fail, stop and fix the failures before continuing. +3. **`make test-cov-check`** (coverage threshold) + - Run `make test-cov-check`. + - Warn the user if coverage is below threshold, but do **not** block the PR. + +### 3. Determine the ticket ID - Extract from the current branch name if it contains `DBA-`. - Otherwise ask the user for the ticket ID. -- Prefix every commit message with the ticket ID: `[DBA-123] Description`. -### 3. Stage and commit +### 4. Stage and commit - Stage relevant files (prefer explicit paths over `git add -A`). -- Commit with `[DBA-XXX] Description of change`. +- Commit following the **Commit Messages** section in `CLAUDE.md`. -### 4. Pause for confirmation +### 5. Pause for confirmation Present the user with: @@ -38,7 +50,7 @@ Present the user with: **Wait for explicit user confirmation before proceeding.** -### 5. Push and create PR +### 6. Push and create PR - Push with `-u` flag: `git push -u origin ` - Create the PR via `gh pr create` using the template: @@ -64,7 +76,7 @@ Present the user with: - [ ] ``` -### 6. Report +### 7. Report Output the PR URL so the user can review it. @@ -72,7 +84,7 @@ Output the PR URL so the user can review it. - Never push to `main`. - Never push without explicit user confirmation. -- Never skip the `[DBA-XXX]` commit prefix when a ticket is known. +- Never skip the commit prefix when a ticket is known (see `CLAUDE.md`). - Never use `git add -A` or `git add .` — stage specific files. - If `gh` CLI is not available, show the push command and PR URL for manual creation. diff --git a/.claude/skills/update-pr/SKILL.md b/.claude/skills/update-pr/SKILL.md new file mode 100644 index 00000000..461e9936 --- /dev/null +++ b/.claude/skills/update-pr/SKILL.md @@ -0,0 +1,52 @@ +--- +name: update-pr +description: Stage, commit, and push follow-up changes to an existing feature branch or PR. Use for quick iterations — after addressing review feedback, fixing a bug on the branch, or adding incremental changes that don't need a new PR. +--- + +# Update PR + +Stage changes, commit, and push to the current feature branch. Designed for +fast iterations on an existing branch or open PR. + +## Steps + +### 1. Verify preconditions + +- Confirm you are NOT on `main`. If on `main`, run the `create-branch` + skill to create a feature branch before continuing. +- Check `git status` for changes to commit. If nothing to commit, inform + the user and stop. + +### 2. Run quality gates + +These are **blocking** — do not commit until both pass. + +1. **`make check`** (ruff + mypy) + - Run `make check`. + - If ruff fails, auto-fix with `uv run ruff check --fix src/databao_cli && uv run ruff format src/databao_cli`, then re-run `make check`. + - If mypy fails after ruff is clean, stop and fix the type errors before continuing. +2. **`make test`** (pytest) + - Run `make test`. + - If tests fail, stop and fix the failures before continuing. + +### 3. Stage and commit + +- Stage relevant files (prefer explicit paths over `git add -A`). +- Extract the ticket ID from the branch name if it contains `DBA-`. +- Commit following the **Commit Messages** section in `CLAUDE.md`. + +### 4. Push + +- Push to the tracked remote branch: `git push`. +- If no upstream is set, push with `-u`: `git push -u origin `. + +### 5. Report + +Confirm the push succeeded and show the commit hash. If a PR exists for +the branch, show the PR URL. + +## Guardrails + +- Never push to `main`. +- Never use `git add -A` or `git add .` — stage specific files. +- Never skip the commit prefix when a ticket is known (see `CLAUDE.md`). diff --git a/.claude/skills/update-pr/evals/evals.json b/.claude/skills/update-pr/evals/evals.json new file mode 100644 index 00000000..1b7da078 --- /dev/null +++ b/.claude/skills/update-pr/evals/evals.json @@ -0,0 +1,37 @@ +{ + "skill_name": "update-pr", + "evals": [ + { + "id": 1, + "prompt": "Push my latest changes to the PR. I'm on branch andrei.gasparian/DBA-200-add-logging.", + "expected_output": "Agent runs quality gates, stages changes, commits with [DBA-200] prefix, and pushes to the existing branch.", + "assertions": [ + "Agent runs make check before committing", + "Agent runs make test before committing", + "Agent commits with a message prefixed by [DBA-200]", + "Agent stages specific files, not git add -A", + "Agent pushes to the current branch" + ] + }, + { + "id": 2, + "prompt": "I fixed the review comments, just push it.", + "expected_output": "Agent stages the changes, commits with ticket prefix from branch name, and pushes.", + "assertions": [ + "Agent runs quality gates before committing", + "Agent extracts ticket ID from branch name if present", + "Agent pushes without creating a new PR" + ] + }, + { + "id": 3, + "prompt": "Update the PR with my changes. I'm on main.", + "expected_output": "Agent detects it is on main and runs the create-branch skill before continuing.", + "assertions": [ + "Agent detects that the current branch is main", + "Agent does NOT push to main", + "Agent runs the create-branch skill to create a feature branch" + ] + } + ] +} diff --git a/CLAUDE.md b/CLAUDE.md index 9646d1c6..0d967150 100755 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -99,8 +99,16 @@ style issues; do not manually fix formatting. `update_issue` (set `State` field). - After creating a PR, move the ticket to **Review** state and add the PR URL as a comment. -- Prefix every commit message with the ticket ID: - `[DBA-123] Description of change`. +## Commit Messages + +- Format: `[DBA-XXX] ` (max 72 chars) +- Use imperative mood: "Add feature", not "Added feature" or "Adds feature" +- Lowercase after the prefix: `[DBA-123] fix auth timeout` +- No trailing period +- If a body is needed, add a blank line after the summary: + - Explain *why*, not *what* (the diff shows what) + - Wrap at 72 characters +- If no ticket exists, omit the prefix — don't invent one ## After Completing Work From 6a290a46ad48a2975a739e4e81a0e1108f53de17 Mon Sep 17 00:00:00 2001 From: Andrei Gasparian Date: Thu, 19 Mar 2026 19:04:13 +0100 Subject: [PATCH 3/3] Simplify nickname detection in create-branch skill Replace fragile branch-scanning shell pipeline with `make nickname` target that extracts the local part from git user.email. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/create-branch/SKILL.md | 10 +++++----- .claude/skills/create-branch/evals/evals.json | 4 ++-- Makefile | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.claude/skills/create-branch/SKILL.md b/.claude/skills/create-branch/SKILL.md index bc0f918a..192f150d 100644 --- a/.claude/skills/create-branch/SKILL.md +++ b/.claude/skills/create-branch/SKILL.md @@ -12,13 +12,13 @@ convention used in this repository. ### 1. Detect the user's nickname -Query existing remote branches to find the most frequent author prefix: +Resolve the nickname using the first approach that succeeds: -```bash -git branch -r | sed -nE 's|^ *origin/([^/]+)/.*|\1|p' | grep -vE '^(dependabot|HEAD|revert-)' | sort | uniq -c | sort -rn -``` +1. **Memory** — check if a stored memory already contains the user's nickname. +2. **`make nickname`** — outputs the local part of `git config user.email` (before `@`). +3. **Ask** — if neither works, ask the user. -Pick the top result. If ambiguous or no branches exist, ask the user. +Once resolved, save the nickname to memory for future conversations. ### 2. Derive a descriptive branch name diff --git a/.claude/skills/create-branch/evals/evals.json b/.claude/skills/create-branch/evals/evals.json index d1fee2cc..c71d53ce 100644 --- a/.claude/skills/create-branch/evals/evals.json +++ b/.claude/skills/create-branch/evals/evals.json @@ -6,7 +6,7 @@ "prompt": "Create a branch for ticket DBA-150 about fixing the status command output.", "expected_output": "Agent detects nickname from remotes, creates a branch like /DBA-150-fix-status-output from origin/main.", "assertions": [ - "Agent runs the nickname detection command against remote branches", + "Agent resolves the nickname from memory or git email", "Agent fetches from origin before creating the branch", "Branch name follows `/` pattern", "Branch is created from origin/main, not from the current HEAD of an unrelated branch", @@ -18,7 +18,7 @@ "prompt": "I need a new branch for some exploratory work, no ticket yet.", "expected_output": "Agent creates a branch with a descriptive name without a ticket prefix.", "assertions": [ - "Agent detects the nickname from remote branches", + "Agent resolves the nickname from memory or git email", "Agent asks or derives a descriptive slug for the branch", "Branch name does NOT include a ticket ID since none was provided", "Agent does NOT require a ticket to proceed" diff --git a/Makefile b/Makefile index 80e030c7..817c55ee 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,9 @@ test-cov-check: e2e-test: uv run --group e2e-tests pytest e2e-tests +nickname: + @git config user.email | cut -d@ -f1 + lint-skills: scripts/validate-agent-guidance.sh