604 lines
27 KiB
Markdown
604 lines
27 KiB
Markdown
# gw-triage Plugin Implementation Plan
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** Build the gw-triage Claude Code plugin: screenshot + Telegram message → classified, deduplicated, Italian Jira issue under the right epic, assigned to the right developer, screenshot attached.
|
||
|
||
**Architecture:** A single git repo that is both a Claude Code plugin and its own marketplace. Two skills (`triage`, `map-repo`) driven by a committed routing config (`config/routing.json`, values fetched live from Jira during this build) and per-repo knowledge profiles (`knowledge/*.md`). Jira writes go through the Atlassian MCP; screenshot attachment goes through the Jira REST API with a personal API token.
|
||
|
||
**Tech Stack:** Claude Code plugin format (plugin.json / marketplace.json / skills), Atlassian MCP (`mcp__plugin_atlassian_atlassian__*` tools), Jira Cloud REST API v3 (attachments via curl), JSON config, Markdown.
|
||
|
||
## Global Constraints
|
||
|
||
- Spec: `docs/design.md` in this repo — the plan implements it 1:1.
|
||
- **Language policy (from spec):** everything humans read is Italian (README, both skills' interactive output, Jira issues). Model-facing text is English (SKILL.md bodies, routing.json, knowledge profiles).
|
||
- **No autonomous git commits.** At the end of each task, list the files created/changed; Giuseppe stages and commits himself. (Overrides the commit steps normally mandated by the plan template.)
|
||
- Working directory for all tasks: `/Users/giuse/Documents/Work/GrowingWay/gw-triage`.
|
||
- All intra-plugin paths inside SKILL.md files use `${CLAUDE_PLUGIN_ROOT}`.
|
||
- Plugin name is exactly `gw-triage` everywhere (plugin.json, marketplace.json, docs).
|
||
- `config/routing.json` must contain zero placeholder values when Task 2 completes — every value fetched from Jira or confirmed by Giuseppe.
|
||
- Routing rules (from spec, fixed): app-android → Fabrizio, app-ios → Antonio, app-shared → Fabrizio (fallback), backend/backoffice/infra → Giuseppe.
|
||
|
||
---
|
||
|
||
### Task 1: Plugin scaffold
|
||
|
||
**Files:**
|
||
- Create: `.claude-plugin/plugin.json`
|
||
- Create: `.claude-plugin/marketplace.json`
|
||
|
||
**Interfaces:**
|
||
- Produces: plugin identity `gw-triage` v`0.1.0`; marketplace source `./`. Task 6 (map-repo skill) references the patch-version bump of this `plugin.json`; the README (Task 7) references the marketplace add/install commands.
|
||
|
||
- [ ] **Step 1: Write `.claude-plugin/plugin.json`**
|
||
|
||
```json
|
||
{
|
||
"name": "gw-triage",
|
||
"description": "Da screenshot + messaggio Telegram a issue Jira instradata al dev giusto",
|
||
"version": "0.1.0",
|
||
"author": {
|
||
"name": "GrowingWay"
|
||
}
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 2: Write `.claude-plugin/marketplace.json`**
|
||
|
||
```json
|
||
{
|
||
"name": "gw-triage",
|
||
"owner": {
|
||
"name": "GrowingWay"
|
||
},
|
||
"plugins": [
|
||
{
|
||
"name": "gw-triage",
|
||
"source": "./",
|
||
"description": "Da screenshot + messaggio Telegram a issue Jira instradata al dev giusto"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 3: Verify**
|
||
|
||
Run: `claude plugin validate .` from the repo root.
|
||
Expected: validation passes. If the `validate` subcommand is unavailable in the installed CLI version, fall back to `python3 -m json.tool .claude-plugin/plugin.json && python3 -m json.tool .claude-plugin/marketplace.json` — both must parse without error.
|
||
|
||
- [ ] **Step 4: Hand off for commit** — list the two files; Giuseppe commits.
|
||
|
||
---
|
||
|
||
### Task 2: Fetch Jira coordinates and write `config/routing.json`
|
||
|
||
This task is interactive (MCP calls + Giuseppe picks epics). Run it inline in the main session, not in a subagent.
|
||
|
||
**Files:**
|
||
- Create: `config/routing.json`
|
||
|
||
**Interfaces:**
|
||
- Consumes: Atlassian MCP tools (load schemas first via ToolSearch: `select:mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources,mcp__plugin_atlassian_atlassian__getVisibleJiraProjects,mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql,mcp__plugin_atlassian_atlassian__lookupJiraAccountId,mcp__plugin_atlassian_atlassian__atlassianUserInfo`).
|
||
- Produces: `config/routing.json` with the exact schema below. Task 5 (triage skill) reads `site`, `cloudId`, `projectKey`, `language`, and `areas.<key>.{epic,assignee.accountId,assignee.name}`.
|
||
|
||
- [ ] **Step 1: Get cloudId and site URL**
|
||
|
||
Call `getAccessibleAtlassianResources`. Record `cloudId` and the site URL (`https://<site>.atlassian.net`).
|
||
|
||
- [ ] **Step 2: Confirm the project**
|
||
|
||
Call `getVisibleJiraProjects`. Present the candidate list to Giuseppe with AskUserQuestion (expected answer: the project whose keys look like `OA-…`). Record `projectKey`.
|
||
|
||
- [ ] **Step 3: List epics**
|
||
|
||
Call `searchJiraIssuesUsingJql` with:
|
||
`project = <projectKey> AND issuetype = Epic AND statusCategory != Done ORDER BY created DESC`
|
||
fields: `summary,status`, maxResults 50. Show the list (key — summary).
|
||
|
||
- [ ] **Step 4: Map areas to epics**
|
||
|
||
AskUserQuestion: which epic corresponds to each area (`app-android`, `app-ios`, `app-shared`, `backend`, `backoffice`, `infra`). Multiple areas may share one epic. If no suitable epic exists for an area, Giuseppe names one to create; create it with `createJiraIssue` (issueTypeName `Epic`) only on his explicit confirmation.
|
||
|
||
- [ ] **Step 5: Resolve account IDs**
|
||
|
||
Call `atlassianUserInfo` for Giuseppe's own accountId. Call `lookupJiraAccountId` for "Fabrizio" and "Antonio" (confirm the matches with Giuseppe if more than one candidate).
|
||
|
||
- [ ] **Step 6: Write `config/routing.json`**
|
||
|
||
Exact schema — fill every `<…>` with the fetched values:
|
||
|
||
```json
|
||
{
|
||
"site": "https://<site>.atlassian.net",
|
||
"cloudId": "<cloudId>",
|
||
"projectKey": "<projectKey>",
|
||
"language": "it",
|
||
"areas": {
|
||
"app-android": { "epic": "<key>", "assignee": { "name": "Fabrizio", "accountId": "<id>" } },
|
||
"app-ios": { "epic": "<key>", "assignee": { "name": "Antonio", "accountId": "<id>" } },
|
||
"app-shared": { "epic": "<key>", "assignee": { "name": "Fabrizio", "accountId": "<id>" } },
|
||
"backend": { "epic": "<key>", "assignee": { "name": "Giuseppe", "accountId": "<id>" } },
|
||
"backoffice": { "epic": "<key>", "assignee": { "name": "Giuseppe", "accountId": "<id>" } },
|
||
"infra": { "epic": "<key>", "assignee": { "name": "Giuseppe", "accountId": "<id>" } }
|
||
}
|
||
}
|
||
```
|
||
|
||
- [ ] **Step 7: Verify**
|
||
|
||
Run: `python3 -m json.tool config/routing.json > /dev/null && grep -c '<' config/routing.json`
|
||
Expected: JSON parses; grep count is `0` (no unfilled placeholders).
|
||
|
||
- [ ] **Step 8: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 3: Knowledge profile format (`knowledge/README.md`)
|
||
|
||
**Files:**
|
||
- Create: `knowledge/README.md`
|
||
|
||
**Interfaces:**
|
||
- Produces: the six required section headings, consumed verbatim by Task 4 (zeus profile) and by the map-repo skill (Task 6): `System identity`, `User-visible surfaces`, `Error fingerprints`, `Symptom → area heuristics`, `Domain glossary`, `Not mine`.
|
||
|
||
- [ ] **Step 1: Write `knowledge/README.md`**
|
||
|
||
```markdown
|
||
# Triage knowledge profiles
|
||
|
||
One file per company codebase, written in English, read by the `triage`
|
||
skill to classify and route reports. Generate or refresh a profile with
|
||
the `map-repo` skill, run from inside the repo being mapped.
|
||
|
||
File name: `<repo-name>.md` (lowercase). Target length 100–200 lines.
|
||
Keep the exact section headings below — the triage skill relies on them.
|
||
|
||
## System identity
|
||
|
||
Name, one-line responsibility, owning developer, and which
|
||
`routing.json` area keys this system maps to.
|
||
|
||
## User-visible surfaces
|
||
|
||
Screens / pages / endpoints / dashboards a reporter might screenshot.
|
||
Include visible titles and labels exactly as they appear on screen.
|
||
|
||
## Error fingerprints
|
||
|
||
What failures from this system look like in a screenshot: banner /
|
||
dialog / toast styles, exact localized error strings (it-it and en-us),
|
||
HTTP/gRPC status codes surfaced to users, what a crash looks like.
|
||
|
||
## Symptom → area heuristics
|
||
|
||
Bullet list of `symptom → area-key`, e.g.
|
||
`payment stuck on "processing" → backend`.
|
||
|
||
## Domain glossary
|
||
|
||
Italian terms reporters actually use, mapped to system concepts
|
||
(e.g. `annunci → Announcement`, `prenotazioni → BookingOrder`).
|
||
|
||
## Not mine
|
||
|
||
Symptoms that look like this system but belong to another area — name
|
||
the correct area key for each.
|
||
```
|
||
|
||
- [ ] **Step 2: Verify** — `grep -c '^## ' knowledge/README.md` returns `6`.
|
||
|
||
- [ ] **Step 3: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 4: Zeus knowledge profile (`knowledge/zeus.md`)
|
||
|
||
**Files:**
|
||
- Create: `knowledge/zeus.md`
|
||
- Read (source repo): `/Users/giuse/Documents/Work/GrowingWay/Zeus` — seed from `docs/context-builder.md`, `Zeus.Errors/` localized error JSONs, `Zeus.Admin/` pages, `Proto/proto/Services/`.
|
||
|
||
**Interfaces:**
|
||
- Consumes: section headings from Task 3.
|
||
- Produces: `knowledge/zeus.md` covering areas `backend`, `backoffice`, `infra`.
|
||
|
||
- [ ] **Step 1: Dispatch one exploration subagent on the Zeus repo**
|
||
|
||
Dispatch an Explore-type agent with this exact prompt:
|
||
|
||
> Survey /Users/giuse/Documents/Work/GrowingWay/Zeus to build a triage profile. Start from docs/context-builder.md for architecture. Then gather, with file evidence: (1) user-visible surfaces per service — the Blazor admin pages in Zeus.Admin (page titles, menu labels as rendered), the gRPC/HTTP endpoints in Proto/proto/Services (service + method names, what app feature each backs: announcements, booking, chat, auth/OTP, payments, policy, support); (2) error presentation — the localized error strings in Zeus.Errors (both it-it and en-us, quote 10–15 representative ones with their error domains), the gRPC status codes the ExceptionInterceptor maps to, what a failed payment or SignalR drop looks like to the app user; (3) infrastructure surface — nginx/TLS termination, docker services, what an environment-down failure looks like from outside (connection refused, 502, TLS errors); (4) Italian domain vocabulary visible to end users and admins (annunci, prenotazioni, segnalazioni, host, ospite, ...); (5) boundaries — symptoms that would look like backend but are actually the Flutter app's rendering/logic, and vice versa. Return a structured report; do not write any file.
|
||
|
||
- [ ] **Step 2: Write `knowledge/zeus.md`**
|
||
|
||
Write the profile from the agent's report + `docs/context-builder.md` knowledge, following the Task 3 template exactly (six headings). Content requirements:
|
||
- `System identity`: Zeus platform = backend (`zeus_auth`, `zeus_property` gRPC APIs), backoffice (`zeus_admin` Blazor dashboard), infra (nginx edge, docker, provisioning) — owner Giuseppe — area keys `backend`, `backoffice`, `infra`.
|
||
- `Symptom → area heuristics` must cover at least: payment stuck/failed after checkout → backend; chat messages not delivered / not received → backend; OTP/SMS login not arriving → backend (Ermes); wrong or missing data shown in app with correct layout → backend; admin dashboard errors or wrong grids → backoffice; site/app entirely unreachable, 502, TLS certificate warnings → infra; visual glitches, overflow stripes, misaligned widgets → app (not mine).
|
||
- `Not mine`: rendering artifacts, platform-specific crashes, store/deployment issues → app areas.
|
||
|
||
- [ ] **Step 3: Verify**
|
||
|
||
Run: `grep -c '^## ' knowledge/zeus.md` → `6`. Manually check each heading is non-empty and the heuristics above are present. Sanity-check 3 error strings quoted in the profile against the actual files in `Zeus.Errors/`.
|
||
|
||
- [ ] **Step 4: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 5: `triage` skill
|
||
|
||
**Files:**
|
||
- Create: `skills/triage/SKILL.md`
|
||
|
||
**Interfaces:**
|
||
- Consumes: `config/routing.json` schema (Task 2), knowledge headings (Task 3), Atlassian MCP tools, `JIRA_EMAIL`/`JIRA_API_TOKEN` env vars.
|
||
- Produces: the `/gw-triage:triage` user flow.
|
||
|
||
- [ ] **Step 1: Write `skills/triage/SKILL.md`**
|
||
|
||
```markdown
|
||
---
|
||
name: triage
|
||
description: Use when converting a bug report or feature request — a screenshot and/or a short message, typically forwarded from the company Telegram chat — into a Jira issue routed to the right developer. Triggers on /triage, "crea una issue da questo", "segnala questo bug", or a pasted/dropped Telegram report with intent to track it.
|
||
---
|
||
|
||
# Triage — da segnalazione a issue Jira
|
||
|
||
You convert an informal report (screenshot + short message) into a
|
||
well-formed Jira issue assigned to the right developer.
|
||
|
||
**All interaction with the user happens in Italian.** This file is
|
||
English for precision; never quote it to the user.
|
||
|
||
The Atlassian MCP tools referenced below live under the
|
||
`mcp__plugin_atlassian_atlassian__` prefix. If they are deferred, load
|
||
them in ONE ToolSearch call before Step 0:
|
||
`select:mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources,mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql,mcp__plugin_atlassian_atlassian__createJiraIssue,mcp__plugin_atlassian_atlassian__addCommentToJiraIssue`
|
||
|
||
## Step 0 — Preflight
|
||
|
||
1. Call `getAccessibleAtlassianResources`. If the tool is missing or
|
||
returns an authentication error, STOP and print this guide in
|
||
Italian, then end the turn:
|
||
- installa il plugin Atlassian: `/plugin install atlassian@claude-plugins-official`
|
||
- esegui `/mcp`, seleziona `atlassian` e completa il login nel browser con l'account aziendale
|
||
- poi rilancia `/triage`
|
||
2. Run `test -n "$JIRA_EMAIL" && test -n "$JIRA_API_TOKEN" && echo ok || echo missing`.
|
||
If `missing`: continue, but tell the user (Italian) that the
|
||
screenshot cannot be attached automatically and point them to the
|
||
"Token API Jira" section of the plugin README
|
||
(`${CLAUDE_PLUGIN_ROOT}/README.md`) — show the 4 token steps inline,
|
||
once, then proceed.
|
||
|
||
## Step 1 — Input
|
||
|
||
Expect a short message (usually Italian) and optionally a screenshot.
|
||
- Screenshot given as a file path (dragged into the prompt): Read it
|
||
for analysis and keep the path for Step 7.
|
||
- Pasted image (no path): analyze it; warn (Italian) that the
|
||
attachment will be skipped — it can be dragged into Jira manually.
|
||
- No screenshot: proceed on the text alone.
|
||
- Neither message nor screenshot: ask (Italian) for at least one.
|
||
|
||
## Step 2 — Load routing and knowledge
|
||
|
||
Read `${CLAUDE_PLUGIN_ROOT}/config/routing.json` and every `.md` file
|
||
in `${CLAUDE_PLUGIN_ROOT}/knowledge/` except `README.md`.
|
||
|
||
## Step 3 — Classify
|
||
|
||
Decide, using the knowledge profiles (error fingerprints, symptom
|
||
heuristics, glossaries, "not mine" sections):
|
||
- **type**: `Bug` (something broken) or `Task` (feature request /
|
||
change / improvement)
|
||
- **area**: exactly one key from `routing.json` `areas`.
|
||
|
||
Platform rules for app issues: visible Android UI or device →
|
||
`app-android`; visible iOS UI or device → `app-ios`; app issue with no
|
||
platform signal → `app-shared`.
|
||
|
||
If genuinely uncertain between two areas, ask the user ONE targeted
|
||
question in Italian (e.g. "Succede solo su iOS o anche su Android?").
|
||
Never more than one question; otherwise decide and state the assumption
|
||
in the draft.
|
||
|
||
## Step 4 — Duplicate check
|
||
|
||
Extract 2–4 distinctive keywords (include Italian and English variants
|
||
of domain terms). Call `searchJiraIssuesUsingJql` with:
|
||
`project = <projectKey> AND text ~ "<keywords>" AND statusCategory != Done ORDER BY created DESC`
|
||
(maxResults 10). Judge similarity by symptom, not wording.
|
||
|
||
If a likely duplicate exists: show it (key, title, status) and ask
|
||
(Italian) whether to comment on it instead of creating a new issue.
|
||
If yes → `addCommentToJiraIssue` with the new report's details (and
|
||
note the screenshot can't be attached to a comment automatically),
|
||
report the link, stop.
|
||
|
||
## Step 5 — Draft (Italian)
|
||
|
||
Build and present:
|
||
- **Titolo**: concise imperative, e.g. "Correggere overflow nella
|
||
schermata prenotazioni su Android".
|
||
- **Descrizione** with sections:
|
||
- *Contesto* — source of the report (chat Telegram, date, reporter
|
||
if known)
|
||
- *Passi per riprodurre* — inferred from screenshot/message; mark
|
||
inferred steps explicitly ("(dedotto dallo screenshot)")
|
||
- *Comportamento atteso / osservato*
|
||
- *Screenshot* — one line describing what it shows
|
||
- **Tipo**: Bug or Task. **Epic**: from routing area. **Assegnatario**:
|
||
from routing area.
|
||
|
||
Show the complete draft and ask ONE confirmation (sì / correggi …).
|
||
Apply corrections; re-confirm only if the area changed (it changes
|
||
epic and assignee).
|
||
|
||
## Step 6 — Create
|
||
|
||
Call `createJiraIssue` with: `cloudId`, `projectKey`, `issueTypeName`
|
||
(`Bug` or `Task`), `summary`, `description`, the area's
|
||
`assignee.accountId`, and `additional_fields: {"parent": {"key": "<area epic>"}}`.
|
||
|
||
If the call fails, report the raw error with a one-line Italian
|
||
summary and stop — nothing partial to clean up (the attachment step
|
||
only runs after successful creation).
|
||
|
||
## Step 7 — Attach screenshot
|
||
|
||
Only if Step 0 found the env vars AND the screenshot is a file path:
|
||
|
||
curl -s -o /tmp/gw-triage-attach.json -w "%{http_code}" -X POST \
|
||
-H "X-Atlassian-Token: no-check" \
|
||
-u "$JIRA_EMAIL:$JIRA_API_TOKEN" \
|
||
-F "file=@<screenshot-path>" \
|
||
"<site>/rest/api/3/issue/<ISSUE-KEY>/attachments"
|
||
|
||
`<site>` comes from routing.json. Success = HTTP 200. Any failure is
|
||
non-fatal: tell the user (Italian) to drag the image into the Jira
|
||
issue manually.
|
||
|
||
## Step 8 — Report
|
||
|
||
Print in Italian: issue key with link `<site>/browse/<KEY>`, type,
|
||
epic, assignee, and whether the screenshot was attached.
|
||
```
|
||
|
||
- [ ] **Step 2: Verify**
|
||
|
||
Run: `head -5 skills/triage/SKILL.md` — frontmatter has `name` and `description`. Cross-check every routing.json field referenced (`site`, `cloudId`, `projectKey`, `areas.<key>.epic`, `areas.<key>.assignee.accountId`) against the Task 2 schema — exact key names.
|
||
|
||
- [ ] **Step 3: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 6: `map-repo` skill
|
||
|
||
**Files:**
|
||
- Create: `skills/map-repo/SKILL.md`
|
||
|
||
**Interfaces:**
|
||
- Consumes: `knowledge/README.md` template (Task 3); `.claude-plugin/plugin.json` version field (Task 1).
|
||
- Produces: the `/gw-triage:map-repo` flow that Fabrizio/Antonio run in the Flutter repo.
|
||
|
||
- [ ] **Step 1: Write `skills/map-repo/SKILL.md`**
|
||
|
||
```markdown
|
||
---
|
||
name: map-repo
|
||
description: Use when generating or refreshing a codebase's triage profile for the gw-triage plugin — run from inside the repo to map. Triggers on /map-repo, "mappa questo repo", "aggiorna il profilo di triage".
|
||
---
|
||
|
||
# Map-repo — profilo di triage del codebase
|
||
|
||
You generate a triage knowledge profile for the repo the user is in,
|
||
and guide them to publish it to the gw-triage plugin repo.
|
||
|
||
**All interaction with the user happens in Italian.** The generated
|
||
profile is written in English (it is read by the triage model, not by
|
||
humans).
|
||
|
||
## Step 1 — Identify the repo
|
||
|
||
- `git rev-parse --show-toplevel` — if not a git repo, ask (Italian)
|
||
to cd into the repo to map and stop.
|
||
- Repo name = basename of the toplevel, lowercased.
|
||
|
||
## Step 2 — Survey
|
||
|
||
Read `${CLAUDE_PLUGIN_ROOT}/knowledge/README.md` (the profile format).
|
||
Dispatch ONE exploration subagent with this prompt, filling <repo-path>:
|
||
|
||
> Survey the codebase at <repo-path> to build a triage profile.
|
||
> Report back, with file evidence: (1) what the system does — main
|
||
> responsibility in one line; (2) user-visible surfaces: screens /
|
||
> pages / endpoints / dashboards a user might screenshot, with their
|
||
> on-screen titles and labels; (3) error presentation: how failures
|
||
> appear to users — banners, dialogs, toasts, their exact wording in
|
||
> every language present, HTTP/gRPC codes surfaced, what a crash looks
|
||
> like; (4) the domain vocabulary users see (menu labels, entity
|
||
> names, Italian terms); (5) integrations that fail visibly (payments,
|
||
> chat, auth, push notifications); (6) what this system does NOT do —
|
||
> adjacent systems it talks to and symptoms that belong to them.
|
||
> Return a structured report; do not write any file.
|
||
|
||
## Step 3 — Write the profile
|
||
|
||
Write `<repo-name>.md` following the six headings of
|
||
`knowledge/README.md`, all sections non-empty, 100–200 lines, English.
|
||
Write it to a temporary location first (the session scratchpad or
|
||
/tmp). Present a short Italian summary to the user with the file path.
|
||
|
||
## Step 4 — Publish
|
||
|
||
Ask (Italian) for the local path of the user's gw-triage checkout;
|
||
offer to `git clone <plugin-repo-url>` if they don't have one (read
|
||
the URL from `git remote get-url origin` run in
|
||
`${CLAUDE_PLUGIN_ROOT}` if available, otherwise ask).
|
||
|
||
With the user's confirmation, in the checkout:
|
||
1. Copy the profile to `knowledge/<repo-name>.md` (overwrite if
|
||
refreshing).
|
||
2. Bump the patch version in `.claude-plugin/plugin.json`
|
||
(e.g. 0.1.0 → 0.1.1).
|
||
3. `git add knowledge/<repo-name>.md .claude-plugin/plugin.json`
|
||
then `git commit -m "knowledge: add/update <repo-name> profile"`
|
||
— ask before committing, and ask again before `git push`.
|
||
4. Tell the user (Italian) that teammates receive the update with
|
||
`/plugin marketplace update gw-triage`.
|
||
```
|
||
|
||
- [ ] **Step 2: Verify**
|
||
|
||
Frontmatter valid (name + description). The six-heading reference matches Task 3's headings. The version-bump path `.claude-plugin/plugin.json` matches Task 1.
|
||
|
||
- [ ] **Step 3: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 7: Italian README
|
||
|
||
**Files:**
|
||
- Create: `README.md`
|
||
|
||
**Interfaces:**
|
||
- Consumes: install commands (Task 1 naming), token flow (spec), skill invocations `/gw-triage:triage`, `/gw-triage:map-repo`.
|
||
- Produces: the guide the triage preflight points users to; `<url-di-questo-repo>` and `<site>` are filled with the real Bitbucket URL (Giuseppe provides at execution) and the Task 2 site URL.
|
||
|
||
- [ ] **Step 1: Write `README.md`** (fill `<site>` from routing.json; leave `<url-di-questo-repo>` only if the remote doesn't exist yet, and flag it in the handoff)
|
||
|
||
```markdown
|
||
# gw-triage
|
||
|
||
Da uno screenshot e due righe su Telegram a una issue Jira fatta bene,
|
||
assegnata al dev giusto.
|
||
|
||
## Installazione (una volta sola)
|
||
|
||
1. **Plugin Atlassian** — in Claude Code:
|
||
`/plugin install atlassian@claude-plugins-official`
|
||
2. **Login Atlassian** — esegui `/mcp`, seleziona `atlassian` e completa
|
||
il login nel browser con l'account aziendale. Verifica che risulti
|
||
*connected*.
|
||
3. **Installa gw-triage**:
|
||
`/plugin marketplace add <url-di-questo-repo>`
|
||
`/plugin install gw-triage`
|
||
4. **Token API** (per allegare gli screenshot — facoltativo ma
|
||
consigliato): sezione sotto.
|
||
|
||
## Token API Jira
|
||
|
||
Serve solo ad allegare gli screenshot alle issue (l'MCP Atlassian non
|
||
supporta gli allegati). Senza token tutto funziona lo stesso: viene
|
||
saltato solo l'allegato.
|
||
|
||
1. Apri <https://id.atlassian.com/manage-profile/security/api-tokens>
|
||
(login con l'account Atlassian aziendale).
|
||
2. **Create API token** → etichetta `gw-triage` → scegli la scadenza →
|
||
**copia subito il token** (viene mostrato una volta sola).
|
||
3. Aggiungi le credenziali al profilo della shell:
|
||
- bash/zsh: `export JIRA_EMAIL="tu@azienda.it"` e
|
||
`export JIRA_API_TOKEN="<token>"`
|
||
- fish: `set -Ux JIRA_EMAIL tu@azienda.it` e
|
||
`set -Ux JIRA_API_TOKEN <token>`
|
||
4. Verifica:
|
||
`curl -s -u "$JIRA_EMAIL:$JIRA_API_TOKEN" <site>/rest/api/3/myself`
|
||
deve restituire il tuo profilo in JSON.
|
||
|
||
⚠️ Il token agisce a tuo nome su Jira: non committarlo mai. Se trapela,
|
||
revocalo dalla stessa pagina. Quando scade, `/triage` continua a
|
||
funzionare — salta solo l'allegato finché non ne esporti uno nuovo.
|
||
|
||
## Uso quotidiano
|
||
|
||
1. Salva lo screenshot dal messaggio Telegram.
|
||
2. In Claude Code: **trascina il file nel prompt** (così può essere
|
||
allegato alla issue), incolla il messaggio e invoca
|
||
`/gw-triage:triage`.
|
||
3. Rispondi all'eventuale domanda di chiarimento, conferma la bozza →
|
||
la issue viene creata e ricevi il link.
|
||
|
||
Funziona anche senza screenshot (solo testo) o con l'immagine incollata
|
||
dagli appunti — in quel caso l'allegato va trascinato in Jira a mano.
|
||
|
||
## Aggiornare la conoscenza dei repo
|
||
|
||
Quando la tua codebase cambia in modo visibile agli utenti, dalla
|
||
cartella del repo esegui `/gw-triage:map-repo` e segui le istruzioni:
|
||
il profilo aggiornato viene pushato qui e gli altri lo ricevono con
|
||
`/plugin marketplace update gw-triage`.
|
||
|
||
## Problemi comuni
|
||
|
||
- **"MCP Atlassian non disponibile"** → passi 1–2 dell'installazione.
|
||
- **"Allegato saltato"** → controlla `JIRA_EMAIL` / `JIRA_API_TOKEN`
|
||
(sezione Token API).
|
||
- **La issue finisce nell'epic sbagliata** → correggi in Jira e apri
|
||
una issue su questo repo per aggiustare `config/routing.json` o il
|
||
profilo in `knowledge/`.
|
||
```
|
||
|
||
- [ ] **Step 2: Verify**
|
||
|
||
`<site>` placeholders replaced with the routing.json value (grep for `<site>` → 0 matches). README is entirely Italian. The four install steps match the spec's Prerequisites section.
|
||
|
||
- [ ] **Step 3: Hand off for commit.**
|
||
|
||
---
|
||
|
||
### Task 8: End-to-end verification, packaging, announcement
|
||
|
||
Interactive — run inline with Giuseppe present.
|
||
|
||
**Files:**
|
||
- Create: none (verification + a drafted Telegram message in chat)
|
||
|
||
**Interfaces:**
|
||
- Consumes: everything above.
|
||
|
||
- [ ] **Step 1: Local install test**
|
||
|
||
Giuseppe runs in a fresh Claude Code session:
|
||
`/plugin marketplace add /Users/giuse/Documents/Work/GrowingWay/gw-triage` then `/plugin install gw-triage`.
|
||
Expected: plugin installs; `/gw-triage:triage` appears; invoking it with no Atlassian session available prints the Italian setup guide (preflight behavior); with the MCP authenticated it proceeds to ask for input.
|
||
|
||
- [ ] **Step 2: Dry-run on real reports**
|
||
|
||
Giuseppe supplies 1–2 real past Telegram reports (screenshot + message). Run the triage flow up to and including the draft (Step 5 of the skill) and STOP before creation. Check: correct type, correct area/assignee/epic, faithful Italian draft, duplicate check ran.
|
||
|
||
- [ ] **Step 3: One live end-to-end**
|
||
|
||
With Giuseppe's explicit go: complete the flow — issue created in Jira, screenshot attached via REST (verify HTTP 200 and the attachment visible in Jira). Giuseppe deletes the issue afterwards or keeps it if it's a real open item.
|
||
|
||
- [ ] **Step 4: Publish handoff (Giuseppe, manual)**
|
||
|
||
Checklist for Giuseppe: create the Bitbucket repo; `git init`/add remote in `/Users/giuse/Documents/Work/GrowingWay/gw-triage`; replace `<url-di-questo-repo>` in README.md with the real URL; commit; push. (No autonomous commits — listed here as his steps.)
|
||
|
||
- [ ] **Step 5: Draft the Telegram announcement (Italian)**
|
||
|
||
Deliver this text in chat for Giuseppe to paste in the group:
|
||
|
||
```
|
||
🛠️ gw-triage — da segnalazione a issue Jira in 30 secondi
|
||
|
||
Basta bug persi in chat. Da oggi: screenshot + due righe → issue Jira
|
||
già assegnata a chi di dovere.
|
||
|
||
Installazione (una volta):
|
||
1. /plugin install atlassian@claude-plugins-official
|
||
2. /mcp → atlassian → login con l'account aziendale
|
||
3. /plugin marketplace add <url-repo>
|
||
4. /plugin install gw-triage
|
||
|
||
Uso: trascina lo screenshot in Claude Code, incolla il messaggio,
|
||
/gw-triage:triage, conferma. Fine.
|
||
|
||
Guida completa (incluso il token per gli allegati) nel README del repo.
|
||
|
||
Fabrizio, Antonio: quando avete 10 minuti, dalla cartella dell'app
|
||
lanciate /gw-triage:map-repo — genera il profilo dell'app e lo pusha
|
||
nel repo del plugin, così il triage impara a riconoscere anche i
|
||
problemi Flutter.
|
||
```
|
||
|
||
- [ ] **Step 6: Final spec pass**
|
||
|
||
Re-read `docs/design.md`; confirm every section is implemented (structure, routing, knowledge, triage flow incl. preflight/duplicates/attach, map-repo, README, verification). Fix gaps before declaring done.
|