@groupby/ai-dev 0.5.16 → 0.5.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +1 -1
  2. package/teams/dqm/skills/check-jenkins-build/SKILL.md +52 -0
  3. package/teams/dqm/skills/create-pr/SKILL.md +96 -0
  4. package/teams/dqm/skills/dqm-implementation-plan/SKILL.md +111 -0
  5. package/teams/dqm/skills/dqm-jira-plan/README.md +33 -0
  6. package/teams/dqm/skills/dqm-jira-plan/SKILL.md +68 -0
  7. package/teams/dqm/skills/promote-to-harness/SKILL.md +59 -0
  8. package/teams/dqm/skills/publish-pr/SKILL.md +73 -0
  9. package/teams/dqm/skills/triage-pr-comments/SKILL.md +119 -0
  10. package/teams/firstspirit-caas/mcp/jira-tools.py +2122 -0
  11. package/teams/firstspirit-caas/mcp/test_bamboo_artifacts.py +315 -0
  12. package/teams/firstspirit-caas/mcp/test_jira_links.py +192 -0
  13. package/teams/firstspirit-caas/mcp/test_update_jira_ticket.py +161 -0
  14. package/teams/firstspirit-caas/resources/mcp-setup.md +57 -0
  15. package/teams/firstspirit-caas/skills/chronicle/SKILL.md +105 -0
  16. package/teams/firstspirit-caas/skills/create-jira-ticket/SKILL.md +183 -0
  17. package/teams/firstspirit-caas/skills/get-jira-ticket/SKILL.md +125 -0
  18. package/teams/firstspirit-caas/skills/handle-red-cve-plan/SKILL.md +316 -0
  19. package/teams/firstspirit-caas/skills/handle-red-cve-plan/references/suppression.md +79 -0
  20. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/gen_suppression.py +116 -0
  21. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/parse_json_report.py +183 -0
  22. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/parse_report.py +255 -0
  23. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_gen_suppression.py +171 -0
  24. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_parse_json_report.py +244 -0
  25. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/test_parse_report.py +464 -0
  26. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/testdata/sample-report.html +39 -0
  27. package/teams/firstspirit-caas/skills/handle-red-cve-plan/scripts/testdata/sample-report.json +76 -0
  28. package/teams/firstspirit-caas/skills/handle-weekly-cve-plans/SKILL.md +238 -0
  29. package/teams/firstspirit-caas/skills/retrospect/SKILL.md +94 -0
  30. package/teams/firstspirit-caas/skills/retrospect/extract_prompts.py +392 -0
  31. package/teams/firstspirit-caas/skills/review/SKILL.md +131 -0
  32. package/teams/firstspirit-caas/skills/review-finalize/SKILL.md +103 -0
  33. package/teams/firstspirit-caas/skills/specify/SKILL.md +239 -0
  34. package/teams/firstspirit-caas/skills/summarise-for-jira-comment/SKILL.md +162 -0
  35. package/teams/firstspirit-caas/skills/write-releasenotes/SKILL.md +177 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groupby/ai-dev",
3
- "version": "0.5.16",
3
+ "version": "0.5.18",
4
4
  "description": "Interactive installer for Rezolve Ai development content",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: check-jenkins-build
3
+ description: Check Jenkins CI build status for current branch or PR and report merge readiness. Use for CI/build status and failed pipeline investigation. Requires Crownpeak Jenkins MCP and user confirmation when job path is ambiguous.
4
+ ---
5
+
6
+ # Check Jenkins Build
7
+
8
+ Requires Crownpeak Jenkins MCP:
9
+
10
+ `https://github.com/Crownpeak/dqm-ai-tools/tree/main/jenkins-mcp`
11
+
12
+ ## Fast Path (Primary)
13
+
14
+ 1. Probe Jenkins MCP with `jenkins_list_jobs`.
15
+ 2. If probe fails, report the exact tool error and stop.
16
+ 3. Resolve branch: `git branch --show-current`.
17
+ 4. If `gh` is available and authenticated, check PR:
18
+
19
+ ```bash
20
+ gh pr list --head <branch> --state open --json number,title,url
21
+ ```
22
+
23
+ 5. If PR exists, target `PR-<number>`.
24
+ 6. If PR does not exist, target URL-encoded branch name.
25
+ 7. If user expects a PR but none is found, ask for PR number directly.
26
+ 8. If `gh` is unavailable/unauthenticated, ask user whether to check branch or PR; if PR, ask PR number.
27
+ 9. Discover job candidates with `jenkins_list_jobs`.
28
+ 10. Validate candidate with `jenkins_get_latest_build`.
29
+ 11. If candidate path is not found, call `jenkins_get_job_info` on nearest existing path segment and refine.
30
+ 12. If multiple plausible paths exist, stop and ask user to confirm. Do not guess.
31
+ 13. Report target, job, build status, duration, and link.
32
+ 14. For in-progress builds, include elapsed time and current stage when available via `jenkins_get_build_status`.
33
+ 15. On failure, ask before pulling logs.
34
+ 16. If user agrees, call `jenkins_get_console_log` and show only first failure excerpt (<= 40 lines).
35
+
36
+ ## Report Template
37
+
38
+ ```text
39
+ Target: <PR # or branch>
40
+ Job: <resolved-job-path>
41
+ Build: #<n> - ✅ SUCCESS | ❌ FAILURE | 🔄 IN_PROGRESS | ⏸ ABORTED (<duration>)
42
+ Link: https://<jenkins-host>/job/<seg1>/job/<seg2>/.../<build>/
43
+ ```
44
+
45
+ ## Reference Notes (Secondary)
46
+
47
+ - Branches with `/` in the name must be URL-encoded before using as Jenkins sub-jobs.
48
+ - Jenkins foldered links require repeating `/job/<segment>/` for each path segment.
49
+ - If branch has never been built, report that explicitly instead of generic failure.
50
+ - If Jenkins MCP is not connected, suggest connecting it and running `/mcp`.
51
+ - If access is denied for a job, report permissions issue and ask for alternate path or access.
52
+ - Jenkins layout varies (top-level, foldered, multibranch); discover dynamically with `jenkins_list_jobs`.
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: create-pr
3
+ description: >-
4
+ Create or complete PRs to team standard: ticketed title, fully filled template
5
+ body, AI trailer, and "AI Assisted" label.
6
+ ---
7
+
8
+ # Create PR
9
+
10
+ ## Fast Path (Primary)
11
+
12
+ 1. Find PR for the current branch:
13
+
14
+ ```sh
15
+ gh pr view --json number,isDraft,title,body,url,baseRefName
16
+ ```
17
+
18
+ 2. If PR exists:
19
+ - Update it in place with `gh pr edit`.
20
+ - Keep `baseRefName` unchanged unless the user explicitly asks to change base.
21
+
22
+ 3. If PR does not exist, resolve effective base in this order:
23
+ - User-specified base branch.
24
+ - Repository default branch from:
25
+
26
+ ```sh
27
+ gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
28
+ ```
29
+
30
+ - Topology candidate from:
31
+
32
+ ```sh
33
+ git fetch --prune
34
+ git log --oneline origin/<default-branch>..HEAD --decorate=short \
35
+ | grep -o 'origin/[^ ,)]*' | grep -v HEAD | sort -u
36
+ ```
37
+
38
+ - If one non-default candidate is found, use it as the candidate base.
39
+ - If candidate is non-default, ask the user to confirm.
40
+ - Verify chosen base exists on `origin`; if missing, fall back to `<default-branch>` and report fallback.
41
+
42
+ 4. Build title as `<TICKET>: <short description>`.
43
+ - Ticket source: spec Ticket field or branch name (for example, `feature/OCD-1234/...`).
44
+ - If no ticket is found, ask user; do not invent one.
45
+ - Keep description concise; put detail in body.
46
+
47
+ 5. Build PR body from repository template in this order:
48
+ - `.github/pull_request_template.md`
49
+ - `.github/PULL_REQUEST_TEMPLATE.md`
50
+ - `.github/PULL_REQUEST_TEMPLATE/*`
51
+ - platform default if none exists
52
+
53
+ 6. Fill every template section truthfully (no placeholders). Append this exact final line:
54
+
55
+ ```text
56
+ 🤖 - Assembled by AI
57
+ ```
58
+
59
+ 7. Write body to a temp file and apply:
60
+
61
+ ```sh
62
+ gh pr edit <number> --title "<TICKET>: <short description>" --body-file <path>
63
+ gh pr create --title "<TICKET>: <short description>" --body-file <path> --base <effective-base>
64
+ ```
65
+
66
+ 8. Ensure `AI Assisted` label exists, then apply to PR:
67
+
68
+ ```sh
69
+ gh label list --search "AI Assisted" --json name --jq '.[].name'
70
+ gh label create "AI Assisted" --description "AI created PR" --color fcd119
71
+ gh pr edit <number> --add-label "AI Assisted"
72
+ ```
73
+
74
+ 9. If Jira skills are available, offer to post PR URL comment:
75
+
76
+ ```text
77
+ **PR:** [<PR title>](<PR URL>)
78
+
79
+ 🤖 **Posted by (AI)**
80
+ ```
81
+
82
+ ## Command Reference (Secondary)
83
+
84
+ - Never merge the PR.
85
+ - Keep draft state as-is unless user asks to change it.
86
+ - Keep existing PR base unchanged unless user asks.
87
+ - Do not assume `main`; always resolve repository default branch.
88
+ - Use `--body-file` for body updates/creation to avoid quoting issues.
89
+
90
+ ## Done
91
+
92
+ Report PR URL and confirm all:
93
+ - title format is correct
94
+ - template sections are fully filled
95
+ - trailer line is present
96
+ - `AI Assisted` label is applied
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: dqm-implementation-plan
3
+ description: >-
4
+ Produce a structured DQM implementation plan from assembled ticket context or
5
+ any written source. Handles scope determination, NNNN folder naming, clarifications,
6
+ architecture scan, phased checklists, and DQM-specific next steps. Typically
7
+ invoked by dqm-jira-plan but can be used standalone with any source material.
8
+ ---
9
+
10
+ # DQM Implementation Plan
11
+
12
+ Self-contained. Produces planning files in `docs/planning/` following DQM conventions.
13
+
14
+ ## Input
15
+
16
+ One of:
17
+ - Assembled context passed from `dqm-jira-plan`
18
+ - A path to an existing document
19
+ - Inline notes or requirements pasted into the conversation
20
+
21
+ ## Defaults
22
+
23
+ | Setting | Value |
24
+ |---------|-------|
25
+ | Project | `OCD` |
26
+ | Team | `Tardigrades` |
27
+ | Product Line | `DQM` |
28
+
29
+ ## Fast Path
30
+
31
+ 1. **Determine scope:**
32
+ - Small (1–3 tasks, single concern): single file `docs/planning/<name>.md`
33
+ - Larger (4+ tasks or cross-cutting): folder `docs/planning/<name>/`
34
+
35
+ 2. **Choose name:** list `docs/planning/`, find the highest existing 4-digit prefix, increment by 1 (start at `0001` if none exist). Pattern: `{NNNN}-{ticket-key-lowercase}-{short-slug}`. Short slug = 2–4 kebab-case words from the summary. Confirm with user if ambiguous; use user-supplied name verbatim if provided.
36
+
37
+ 3. **Scan architecture docs:**
38
+ - Read `docs/architecture/` — at minimum the README and any file relevant to the task. Note the gap if absent.
39
+ - Read the project's framework/dependency constraint documentation (e.g. `AGENTS.md`, `CLAUDE.md`, or equivalent) before proposing any concrete type, API, or library construct.
40
+ - For any dependency or framework version that may post-date the model training window, verify the API exists in that version before naming it in the plan — do not rely on training data for version-specific details.
41
+ - If the project provides a docs-fetching skill for the framework in use, invoke it. Otherwise use `WebFetch` or `WebSearch` against the library's official docs.
42
+ - A plan that names the wrong type propagates the mistake to every downstream agent.
43
+
44
+ 4. **Scan existing plans:** check `docs/planning/` for related plans. Note any this plan relates to or supersedes.
45
+
46
+ 5. **Write clarifications:** surface ambiguities from the source with assumed answers. See Clarifications Template below. Write the file immediately and proceed to the plan without stopping.
47
+
48
+ 6. **Write plan:** include all required sections (see Plan Output Templates below). Always include:
49
+ - Architecture context citing specific files from `docs/architecture/`
50
+ - Decisions (including those inherited from clarifications)
51
+ - Open questions that could not be assumed away
52
+ - Phased checklist with testing and documentation steps
53
+ - Per-task detail: exact files to create/modify, patterns to follow, edge cases, test requirements
54
+ - DQM next steps:
55
+ - Update OCD ticket status to In Progress
56
+ - Add comment to ticket linking to `docs/planning/<name>/`
57
+ - Create Jira subtasks for each phase if Tardigrades team tracks at that level
58
+
59
+ ## Reference Notes
60
+
61
+ ### Clarifications Template
62
+
63
+ ```markdown
64
+ # Clarifications: {TICKET-KEY} — {Summary}
65
+
66
+ Ambiguities identified before planning. Override any ANSWER: line and ask for the plan to be updated.
67
+
68
+ ---
69
+
70
+ ### 1. {Short question title}
71
+
72
+ {Why this is ambiguous.}
73
+
74
+ ANSWER: {Assumed answer with brief reasoning.}
75
+ ```
76
+
77
+ ### Plan Output Templates
78
+
79
+ **Single file** (`docs/planning/<name>.md`):
80
+
81
+ ```
82
+ # <Title>
83
+
84
+ <One-paragraph summary of what this plan accomplishes and why.>
85
+
86
+ ## Source
87
+ ## Architecture context
88
+ ## Decisions
89
+ ## Open questions
90
+ ## Implementation checklist
91
+ ## Detail (per task)
92
+ ## Next steps
93
+ ```
94
+
95
+ **Folder** (`docs/planning/<name>/`):
96
+
97
+ ```
98
+ README.md # intent, source, links to plan/
99
+ clarifications.md
100
+ plan/
101
+ README.md # decisions, checklist, links to sub-plans
102
+ <sub-plan-1>.md
103
+ ...
104
+ ```
105
+
106
+ ### Edge Cases
107
+
108
+ - No `docs/architecture/`: note gap in plan; suggest creating it as follow-up.
109
+ - Source has no acceptance criteria: proceed with summary + comments; note gap in clarifications.
110
+ - Conflicting decisions in source: surface each as an open question.
111
+ - User disagrees with a clarification assumption: edit the `ANSWER:` line and ask for the plan to be regenerated.
@@ -0,0 +1,33 @@
1
+ # dqm-jira-plan
2
+
3
+ Generate an implementation plan starting from a DQM Jira ticket (`OCD-XXXX`). Fetches the full ticket context — epic hierarchy, acceptance criteria, subtasks, linked issues, recent comments, and linked Confluence pages — then produces a structured plan inline using the `implementation-plan` format.
4
+
5
+ ## Requirements
6
+
7
+ Prefers `atlassian-rovo` MCP — no setup needed if it's available in your environment.
8
+
9
+ **REST API fallback:** set these environment variables when MCP is unavailable:
10
+
11
+ ```sh
12
+ export JIRA_EMAIL=your.email@example.com
13
+ export JIRA_API_TOKEN=<token from https://id.atlassian.com/manage-profile/security/api-tokens>
14
+ ```
15
+
16
+ The skill connects to `https://attraqt.atlassian.net` by default. The same credentials cover both Jira and Confluence.
17
+
18
+ ## Example prompts
19
+
20
+ - `/dqm-jira-plan OCD-1234`
21
+ - "Plan the implementation for OCD-567"
22
+ - "Create a plan from ticket 1234" *(bare number resolves to OCD-1234)*
23
+
24
+ ## DQM context
25
+
26
+ - Project key: `OCD-XXXX`
27
+ - Product line filter: `"Crownpeak Product Line" = DQM`
28
+ - Assigned team: Tardigrades
29
+
30
+ ## Related
31
+
32
+ - [`jira-plan`](../../../../skills/library/jira-plan/) — the library version of this skill; requires Atlassian MCP and delegates to `implementation-plan`
33
+ - [`implementation-plan`](../../../../skills/library/implementation-plan/) — use directly when you have ticket details but no Jira access
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: dqm-jira-plan
3
+ description: >-
4
+ Fetch a DQM Jira ticket from attraqt.atlassian.net and assemble full context,
5
+ then delegate to dqm-implementation-plan to produce the plan. Prefers Atlassian
6
+ MCP (atlassian-rovo); falls back to REST API with JIRA_EMAIL + JIRA_API_TOKEN.
7
+ DQM tickets use OCD-XXXX.
8
+ ---
9
+
10
+ # DQM Jira Plan
11
+
12
+ Fetches ticket context and delegates planning to `dqm-implementation-plan`.
13
+
14
+ ## Defaults
15
+
16
+ | Setting | Value |
17
+ |---------|-------|
18
+ | Project | `OCD` — bare numbers resolve to `OCD-N` |
19
+ | Instance | `https://attraqt.atlassian.net` (override with `JIRA_URL`) |
20
+ | Team | `Tardigrades` |
21
+ | Product Line | `DQM` |
22
+
23
+ ## Fast Path
24
+
25
+ 1. **Resolve key:** Full key → use directly. Bare number → prepend `OCD-`. Try git branch (e.g. `OCD-1234-slug` → `OCD-1234`). Unknown → ask user. Non-OCD key → proceed as-is and note deviation.
26
+ 2. **Connectivity:**
27
+ - MCP available (`atlassian-rovo`): use MCP tools for all calls.
28
+ - MCP unavailable: verify `JIRA_EMAIL` + `JIRA_API_TOKEN` are set. If missing, stop — see missing credentials message in Reference Notes. All REST calls target `${JIRA_URL:-https://attraqt.atlassian.net}`.
29
+ 3. **Fetch ticket:** `jira_get_issue(issue_key="{TICKET-KEY}")`. Extract: summary, description, status, assignee, priority, story points, acceptance criteria (`customfield_10016` or field containing "acceptance"), issue type, Team field, Crownpeak Product Line field. Flag if Team ≠ `Tardigrades` or Product Line ≠ `DQM`.
30
+ 4. **Fetch subtasks:** `jira_search(jql="parent = {TICKET-KEY} ORDER BY status ASC, priority DESC")`
31
+ 5. **Fetch linked issues:** extract from `fields.issuelinks` in the issue response.
32
+ 6. **Fetch comments:** last 10, most recent first. REST: see Reference Notes.
33
+ 7. **Fetch epic context:**
34
+ - Detect: `fields.parent` (issuetype = Epic) or `fields.customfield_10014`.
35
+ - If found: fetch epic summary/description; fetch siblings: `jira_search(jql='"Epic Link" = {EPIC-KEY} AND "Crownpeak Product Line" = DQM AND key != {TICKET-KEY} ORDER BY status ASC, priority DESC')`. If JQL fails on that field, drop the filter and retry.
36
+ - Large epics (20+ siblings): summarise; focus on In Progress and To Do.
37
+ - No epic: note as orphaned and continue.
38
+ 8. **Fetch Confluence pages:** get remote links from issue (`/rest/api/3/issue/{TICKET-KEY}/remotelink`); filter for `atlassian.net/wiki` URLs; fetch each page truncated to ~500 words. Extract page ID from URL path after `/pages/`. MCP: `confluence_get_page(page_id="{PAGE_ID}")`. If 403/404: include title + URL only.
39
+ 9. **Delegate to `dqm-implementation-plan`:** pass the assembled context as source material. The ticket key becomes the story name (e.g. `ocd-1234`) unless the user specified otherwise.
40
+
41
+ ## Reference Notes
42
+
43
+ ### REST Fallback Commands
44
+
45
+ Base: `curl -s -u "$JIRA_EMAIL:$JIRA_API_TOKEN" -H "Content-Type: application/json" "${JIRA_URL:-https://attraqt.atlassian.net}"`
46
+
47
+ | Data | Path |
48
+ |------|------|
49
+ | Issue | `/rest/api/3/issue/{TICKET-KEY}` |
50
+ | Subtasks | `/rest/api/3/search?jql=parent+%3D+{TICKET-KEY}+ORDER+BY+status+ASC` |
51
+ | Comments | `/rest/api/3/issue/{TICKET-KEY}/comment?maxResults=10&orderBy=-created` |
52
+ | Remote links | `/rest/api/3/issue/{TICKET-KEY}/remotelink` |
53
+ | Confluence page | `/wiki/rest/api/content/{PAGE_ID}?expand=body.view` — extract `body.view.value`, strip HTML tags |
54
+
55
+ ### Missing Credentials Message
56
+ ```
57
+ Missing Jira credentials. Please set:
58
+ export JIRA_EMAIL=your.email@example.com
59
+ export JIRA_API_TOKEN=<token from https://id.atlassian.com/manage-profile/security/api-tokens>
60
+ ```
61
+
62
+ ### Edge Cases
63
+
64
+ - Ticket not found (404): report clearly; may be moved, deleted, or inaccessible.
65
+ - Non-OCD key: proceed as-is; note deviation from standard DQM project.
66
+ - No description: proceed with summary + comments; note gap in clarifications.
67
+ - Conflicting decisions in comments: pass them as open questions in the assembled context.
68
+ - `"Crownpeak Product Line"` JQL not searchable: drop filter, retry, note fallback.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: promote-to-harness
3
+ description: Promote an approved harness candidate into `coding-guidelines.md`, `AGENTS.md`, or `.github/copilot-instructions.md` to prevent repeat AI mistakes.
4
+ ---
5
+
6
+ Add one rule at a time to the correct harness file.
7
+
8
+ Do not edit harness files until the user confirms both rule text and target file.
9
+
10
+ ## Harness file responsibilities
11
+
12
+ - `coding-guidelines.md`: coding patterns, naming, Java/Spring conventions, test strategy.
13
+ - `AGENTS.md`: workflow, TDD, packaging, release, AWS, pipeline constraints.
14
+ - `.github/copilot-instructions.md`: quick inline Copilot constraints.
15
+
16
+ When in doubt: technical rule -> `coding-guidelines.md`; process rule -> `AGENTS.md`.
17
+
18
+ ## 1. Receive the candidate
19
+
20
+ Accept one candidate with all required fields:
21
+ - issue description
22
+ - proposed rule text (one imperative sentence)
23
+ - target file (one of the three above)
24
+ - source (PR/comment/reference)
25
+
26
+ If any field is missing, ask before proceeding.
27
+
28
+ ## 2. Check for duplicates
29
+
30
+ Read the target harness file and check whether an equivalent rule already exists.
31
+
32
+ - Match found: quote existing text and ask whether to refine instead of adding.
33
+ - No match: proceed.
34
+
35
+ ## 3. Propose placement
36
+
37
+ Identify section and exact insertion point, then show:
38
+ - Section
39
+ - Position (after line N / anchor text)
40
+ - Proposed addition (`- <rule text>`)
41
+
42
+ Ask for confirmation before writing.
43
+
44
+ ## 4. Apply
45
+
46
+ On confirmation, insert the rule into the target file at the agreed position.
47
+
48
+ Prefer appending to an existing relevant list; keep surrounding style.
49
+
50
+ ## 5. Confirm and summarise
51
+
52
+ Report:
53
+
54
+ - file and section updated
55
+ - rule text as written
56
+ - source reference
57
+
58
+ Suggested commit message:
59
+ `docs: (<JIRA-KEY>) promote harness rule from <source>` (when available), otherwise `docs: promote harness rule from <source>`
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: publish-pr
3
+ description: >-
4
+ Publish a draft PR for review: verify it's review-ready (description in sync with
5
+ the Jira ticket and the actual diff, no unchecked checklist items, reviewed by an AI
6
+ agent with no open agent comments), take it out of draft, and announce it in the team
7
+ Slack channel. Use when the user says "publish/release this PR", "take the PR out of
8
+ draft", or invokes /publish-pr.
9
+ ---
10
+
11
+ # Publish PR
12
+
13
+ Stages run in order: **verify → un-draft → announce**. Verify is blocking: if any check fails, report
14
+ all results and STOP — do not un-draft or post. Continue only if the user says "publish anyway".
15
+ Never merge; never change the base.
16
+
17
+ ## 1) Locate
18
+
19
+ ```sh
20
+ gh pr view --json number,isDraft,title,body,url,baseRefName,headRefName
21
+ ```
22
+
23
+ No PR → stop, suggest `create-pr`. Resolve ticket (`OCD-XXXX`) from title/branch; if none, ask.
24
+
25
+ ## 2) Verify (BLOCKING — run all, report together)
26
+
27
+ - **a. PR-body checklist** — no unticked `- [ ]` in the PR description (unless user marked one N/A).
28
+ - **a2. Spec/plan checklists** — for any spec/planning doc in this PR's diff (`specs/**`,
29
+ `docs/planning/**`), no unticked `- [ ]` remains; these track the story's ACs/phases. List file+line of any.
30
+ - **b. Jira sync** — fetch ticket from `attraqt.atlassian.net` (Atlassian MCP; fall back to REST with
31
+ `JIRA_EMAIL`+`JIRA_API_TOKEN`). Fail if PR claims scope the ticket lacks, omits a stated AC, or
32
+ summaries materially disagree. Wording differences are fine.
33
+ - **c. Diff sync** — `gh pr diff <number>`. Fail if the body describes work absent from the diff, or
34
+ the diff makes significant changes the body never mentions.
35
+ - **d. AI review** — PR must have ≥1 AI-agent review and no unresolved threads it started. Agent =
36
+ reviewer login like `copilot-pull-request-reviewer[bot]`, `Copilot`, or a clearly-review `[bot]`.
37
+
38
+ ```sh
39
+ gh pr view <number> --json reviews --jq '.reviews[] | {author:.author.login, state:.state}'
40
+ gh api graphql -f query='query($o:String!,$r:String!,$p:Int!){repository(owner:$o,name:$r){
41
+ pullRequest(number:$p){reviewThreads(first:100){nodes{isResolved comments(first:1){nodes{author{login}}}}}}}}' \
42
+ -F o=<owner> -F r=<repo> -F p=<number>
43
+ ```
44
+
45
+ Fail (and list specifics) if no agent review exists — request one via `request_copilot_review` —
46
+ or if any thread whose first comment is by an agent has `isResolved:false`.
47
+
48
+ ## 3) Un-draft (only after all pass)
49
+
50
+ ```sh
51
+ gh pr ready <number>
52
+ ```
53
+
54
+ Already non-draft → note it, continue.
55
+
56
+ ## 4) Announce in Slack
57
+
58
+ No Slack tool → skip, report "published, Slack skipped (no connection)". Otherwise:
59
+
60
+ 1. Resolve `#tardigrades` (Crownpeak) via `slack_search_channels` (query `tardigrades`); if ambiguous, confirm with user.
61
+ 2. Compose a short message: **repo name**, **ticket title + key**, **PR link**, **1–2 line summary**.
62
+ Get the repo via `gh repo view --json name --jq .name`. Example:
63
+ ```text
64
+ :eyes: Ready for review — `dqm-scim-service` — *OCD-33443: GET /Users/{id}*
65
+ <PR_URL|#NN Add GET /Users/{id}>
66
+ Returns a single user by id; DELETE now 404s on unknown/cross-tenant.
67
+ ```
68
+ 3. Show the exact text + target channel and wait for explicit approval (revise + re-confirm on edits).
69
+ 4. Post with `slack_send_message` only after approval (or `slack_send_message_draft` if user prefers to send it).
70
+
71
+ ## Done
72
+
73
+ Report: checks passed · PR now ready (or already was) · Slack posted to `#tardigrades` / skipped / not approved.
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: triage-pr-comments
3
+ description: Triage open PR review comments and return recommendations before any code/reply/git write actions.
4
+ ---
5
+
6
+ Triage GitHub PR comments in analysis-only mode.
7
+
8
+ ## Operating mode (default)
9
+
10
+ - No file edits.
11
+ - No GitHub replies.
12
+ - No `git add`, `git commit`, or `git push`.
13
+ - Do not perform any write action unless explicitly approved by the user.
14
+ - Do not auto-transition from triage to implementation; wait for explicit per-comment approval.
15
+
16
+ Use `gh` when available. If `gh` is unavailable/unauthenticated, ask the user for PR link + comment context and continue manually.
17
+
18
+ ## 1) Build unresolved triage set
19
+
20
+ Preferred source: review-thread metadata + issue-level comments.
21
+
22
+ - Include review threads where:
23
+ - `isResolved == false`
24
+ - `isOutdated == false`
25
+ - From each included thread, use only the latest comment as the actionable item.
26
+ - Include issue-level PR comments that still require action.
27
+ - Do not exclude bot authors.
28
+ - De-duplicate by comment ID/URL.
29
+ - Sort newest first by `updatedAt`/`updated_at`.
30
+
31
+ If user asks for "today" or "recent", apply recency filter after unresolved-set construction.
32
+
33
+ ## 2) Classify each comment (exactly one)
34
+
35
+ - `requires-code-change`
36
+ - `requires-doc-change`
37
+ - `explanation-only`
38
+ - `needs-clarification`
39
+ - `decline-with-reason`
40
+
41
+ For each comment, capture:
42
+
43
+ 1. Assessment (request + validity)
44
+ 2. Proposed action (minimal code/doc/test change plan; no edits yet)
45
+ 3. Impact/risk (scope, regressions, dependencies)
46
+ 4. Verification plan (tests/lint/checks if implemented)
47
+ 5. Draft reply (concise, professional, technical refs in backticks)
48
+ 6. Harness candidate (optional):
49
+ - rule text (single imperative sentence)
50
+ - target file: `docs/coding-guidelines.md`, `AGENTS.md`, or `.github/copilot-instructions.md`
51
+
52
+ Inline draft-reply protocol:
53
+ - Start with `🤖 **(AI):**`
54
+ - Use a factual/professional tone
55
+ - If code change: what changed + why (1-2 sentences)
56
+ - If no code change: clear technical reasoning, not acknowledgement-only text
57
+ - Use backticks for technical references (`files`, `symbols`, `flags`, `variables`)
58
+
59
+ ## 3) Ambiguity rule
60
+
61
+ If intent is ambiguous or multiple valid fixes exist, stop and ask user to choose:
62
+
63
+ Comment <id> is ambiguous. Which direction should I take?
64
+ 1) <option-a>
65
+ 2) <option-b>
66
+ 3) <option-c>
67
+
68
+ Do not guess.
69
+
70
+ ## 4) Return prioritized triage report
71
+
72
+ Group by priority:
73
+
74
+ - High: correctness/security/data loss/regression risk
75
+ - Medium: behavior/test coverage/maintainability
76
+ - Low: style/wording/non-functional nits
77
+
78
+ For each comment, return:
79
+
80
+ - ID + link/context
81
+ - Classification
82
+ - Decision: `implement` | `reply-only` | `clarify` | `decline`
83
+ - Proposed change summary (no edits; specify code vs doc-only)
84
+ - Draft reply
85
+ - Verification commands (if implemented)
86
+ - Harness candidate (rule + target file) or blank
87
+
88
+ Also include totals:
89
+
90
+ - comments by classification
91
+ - decisions (`implement` / `reply-only` / `clarify` / `decline`)
92
+ - harness candidate count by target file
93
+ - open questions needing user input
94
+
95
+ ## 5) Ask for execution approval
96
+
97
+ Ask exactly:
98
+
99
+ 1. Which comment IDs should be implemented now?
100
+ 2. Which draft replies should be posted now?
101
+ 3. Run verification commands after implementation? (yes/no)
102
+ 4. Stage/commit/push after verification? (yes/no)
103
+ 5. Promote any harness candidates now? (yes/no; list IDs)
104
+
105
+ If posting replies is approved, use this posting protocol:
106
+
107
+ - Post only after related implementation/verification is complete for that comment.
108
+ - ID safety: never use GraphQL node IDs (for example `PRRC_*`) for REST reply endpoints; use numeric PR review comment IDs from `repos/<owner>/<repo>/pulls/<number>/comments`.
109
+ - Inline review-comment reply endpoint:
110
+ - `repos/<owner>/<repo>/pulls/<number>/comments/<comment_id>/replies`
111
+ - Issue-level PR comment endpoint:
112
+ - `repos/<owner>/<repo>/issues/<number>/comments`
113
+ - JSON safety: do not build non-trivial `{"body":"..."}` payloads inline; serialize with a JSON tool and post via `--input <json-file>`.
114
+ - Temp-file safety: create payload files with `mktemp`; if `/tmp` is not writable, use a workspace-local temp path.
115
+ - Preflight: verify target comment exists and is replyable before posting.
116
+ - On `404`/`400` posting errors, stop and fix ID/payload generation before retrying; do not mark as posted.
117
+ - PowerShell safety: avoid `gh api -f body="..."` for markdown/backticks; write JSON body to a UTF-8 (no BOM) temp file and post with `--input <tmp-file>`.
118
+
119
+ Do not execute write actions without explicit approval.