docs: implementation plan for Codex support; fix search endpoint to v3 search/jql

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Murphy Freelance
2026-07-10 19:22:10 +02:00
parent a967f5c38e
commit a7dcc361c0
2 changed files with 774 additions and 1 deletions

View File

@@ -114,7 +114,7 @@ or invalid netrc → stop with `$setup` instructions.
| Step | MCP mode (unchanged) | REST mode |
|---|---|---|
| Preflight | `getAccessibleAtlassianResources` | `GET /rest/api/2/myself` → expect 200 |
| Duplicate search | `searchJiraIssuesUsingJql` | `GET /rest/api/2/search?jql=<urlencoded>` |
| Duplicate search | `searchJiraIssuesUsingJql` | `GET /rest/api/3/search/jql?jql=<urlencoded>` (the v2/v3 `/search` endpoints were removed by Atlassian in 2025) |
| Create | `createJiraIssue` | `POST /rest/api/2/issue` (JSON body: project, issuetype, summary, plain-text description, assignee accountId, parent epic) |
| Comment on duplicate | `addCommentToJiraIssue` | `POST /rest/api/2/issue/{key}/comment` |
| Attach screenshot | curl (as today) | same curl, `--netrc-file` |

773
docs/codex-support-plan.md Normal file
View File

@@ -0,0 +1,773 @@
# Codex CLI Support 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:** Make the gw-triage skills (triage, setup, map-repo) work under OpenAI Codex CLI with full parity, from the same repo, without breaking the Claude Code flow.
**Architecture:** Shared SKILL.md files that resolve their root via `${CLAUDE_PLUGIN_ROOT}` or their own real path, branch between Atlassian MCP (Claude Code) and Jira REST v2 via curl (Codex), and read credentials from a single netrc file at `~/.config/gw-triage/netrc` written by the setup skill. Codex installation = clone + symlinks into `~/.agents/skills/` created by `install-codex.sh`.
**Tech Stack:** SKILL.md (Agent Skills spec), POSIX sh, curl, Jira Cloud REST API v2.
**Spec:** `docs/codex-support-design.md` (approved 2026-07-10).
## Global Constraints
- All user interaction in the skills happens in Italian; SKILL.md prose stays in English.
- Never put a literal token on a shell command line or in a reply; credentials move only via files (netrc, mode 600) or unexpanded `$VAR` references.
- Netrc path is exactly `~/.config/gw-triage/netrc`. Codex skills dir is exactly `~/.agents/skills`.
- Jira REST calls use API v2 (`/rest/api/2/…`) except attachments (`/rest/api/3/issue/<KEY>/attachments`) and JQL search (`/rest/api/3/search/jql` — the v2 search endpoint was removed by Atlassian in 2025).
- On Claude Code without MCP, triage STOPS with the install guide — REST mode is not a fallback there.
- On Codex the token is REQUIRED; on Claude Code it remains optional (attachments only).
- Skill frontmatter `name:` values must not change (`triage`, `setup`, `map-repo`) — they define the Claude Code commands.
- Claude Code MCP behavior in triage is unchanged: same tools, same cloudId usage.
---
### Task 1: `install-codex.sh`
**Files:**
- Create: `install-codex.sh` (repo root, executable)
**Interfaces:**
- Produces: idempotent script that symlinks `skills/{triage,setup,map-repo}` into `~/.agents/skills/`. README (Task 5) references it as `./install-codex.sh`.
- [ ] **Step 1: Write the script**
```sh
#!/bin/sh
# Install the gw-triage skills for OpenAI Codex CLI by symlinking them
# into ~/.agents/skills. Safe to re-run; updates arrive via `git pull`
# in this clone (symlinks keep pointing at the updated files).
set -eu
repo_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
dest="${HOME}/.agents/skills"
mkdir -p "$dest"
for skill in triage setup map-repo; do
ln -sfn "$repo_dir/skills/$skill" "$dest/$skill"
echo "linked $dest/$skill -> $repo_dir/skills/$skill"
done
echo "Fatto. Per aggiornare in futuro: git -C \"$repo_dir\" pull"
```
- [ ] **Step 2: Make it executable and verify against a scratch HOME**
Run (fish syntax, since the user shell is fish; use `bash -c` to keep it portable):
```bash
chmod +x install-codex.sh
bash -c 'HOME=$(mktemp -d) && ./install-codex.sh && ls -l "$HOME/.agents/skills" && readlink "$HOME/.agents/skills/triage"'
```
Expected: three `linked …` lines, `ls` shows `map-repo`, `setup`, `triage` as symlinks, `readlink` prints `<repo>/skills/triage`. Re-run the script against the same HOME to confirm idempotency (no error, same links).
- [ ] **Step 3: Commit**
```bash
git add install-codex.sh
git commit -m "feat: add Codex CLI installer (symlinks into ~/.agents/skills)"
```
---
### Task 2: Rewrite `skills/setup/SKILL.md` for the shared netrc store
**Files:**
- Modify: `skills/setup/SKILL.md` (full rewrite of the body; frontmatter `name` unchanged)
**Interfaces:**
- Produces: credentials at `~/.config/gw-triage/netrc` in the format `machine <host>` / `login <email>` / `password <token>`, mode 600. Task 3 (triage) consumes this file via `curl --netrc-file`.
- [ ] **Step 1: Replace the file content**
Write `skills/setup/SKILL.md` with exactly:
````markdown
---
name: setup
description: Use when configuring the Jira API credentials for gw-triage — first-time setup, an "allegato saltato" warning from triage, missing or expired credentials, or replacing a revoked token. Triggers on /gw-triage:setup, $setup, "configura il token", "gli allegati non funzionano".
---
# Setup — token API Jira guidato
You guide the user through creating a Jira API token and storing it in
the gw-triage netrc file. The `triage` skill reads that file for its
REST calls: screenshot attachments on every platform, plus search /
create / comment when running under Codex.
**All interaction with the user happens in Italian.** This file is
English for precision; never quote it to the user.
## Environment
- **Root**: `${CLAUDE_PLUGIN_ROOT}` if that variable is set; otherwise
the real path of this skill's own directory (resolve symlinks, e.g.
with `realpath`), two levels up.
- **Store**: `~/.config/gw-triage/netrc`, mode 600. curl reads it at
call time on every platform, so changes take effect immediately — no
session restart, no shell configuration.
- **Host**: the `site` value in `<root>/config/routing.json` without
the scheme (e.g. `growingway.atlassian.net`).
**Keep the token out of replies and displayed commands.** Refer to it
as "il token" and never repeat its value. Never inline a literal token
on a shell command line — it ends up in the transcript and the process
list. Write credentials into the netrc file with the file-writing
tool, then let curl read them via `--netrc-file`.
The verification call used throughout:
curl -s -o /dev/null -w "%{http_code}" \
--netrc-file ~/.config/gw-triage/netrc \
https://<host>/rest/api/2/myself
## Step 0 — Check existing configuration
1. If `~/.config/gw-triage/netrc` exists and is readable, run the
verification call.
- `200` → tell the user (Italian) the token already works and ask
whether they want to replace it anyway. If not, stop.
- anything else → tell them the stored token no longer works
(probably expired or revoked) and continue to Step 1.
2. Otherwise look for legacy credentials, in order:
- session env: `test -n "$JIRA_EMAIL" && test -n "$JIRA_API_TOKEN" && echo session || echo unset`
- `~/.claude/settings.json` (if it exists): `env.JIRA_EMAIL` /
`env.JIRA_API_TOKEN`.
If found in either place: write them to the netrc (Step 2 format,
chmod 600) and run the verification call.
- `200` → tell the user (Italian) the existing credentials were
migrated to the new store and work immediately; then do Step 3
(clean up legacy stores) and Step 4. Done — skip token creation.
- anything else → delete the netrc just written, tell them the old
token no longer works, continue to Step 1.
3. Nothing found → first-time setup, continue to Step 1.
## Step 1 — Token creation (user, in the browser)
Print in Italian, compactly:
1. Apri <https://id.atlassian.com/manage-profile/security/api-tokens>
(login con l'account Atlassian aziendale).
2. **Create API token** → nome `gw-triage` → scegli la scadenza →
**copia subito il token** (viene mostrato una volta sola).
3. Incolla qui email aziendale e token (vanno bene anche su due righe).
Add one line: il token verrà salvato in chiaro in
`~/.config/gw-triage/netrc` sul suo computer, quindi non condividere né
il file né questa conversazione.
End the turn and wait. If the reply contains only one of the two
values, ask for the missing one. If the user can't create the token
(no permission, page unreachable), stop and suggest asking whoever
manages the Atlassian accounts.
## Step 2 — Save, then verify
1. Create `~/.config/gw-triage/` if missing. Write the netrc file with
the file-writing tool:
machine <host>
login <email>
password <token>
Then `chmod 600 ~/.config/gw-triage/netrc`.
2. Run the verification call.
- `200` → Step 3.
- `401`/`403` → wrong email or token (a common cause: copied with a
trailing space or truncated). Ask the user to re-copy and
re-paste, rewrite the file, verify again; after the third failed
verification overall, delete the netrc file, stop, and suggest
creating a fresh token.
- Anything else (timeout, DNS) → network problem, not credentials:
report it and stop. Leave the netrc in place — it may verify fine
later.
## Step 3 — Clean up legacy stores
1. `~/.claude/settings.json`: if it exists and has `env.JIRA_EMAIL` /
`env.JIRA_API_TOKEN`, offer (Italian) to remove those two keys —
with the file tools (Read + Edit), never shell text-mangling, and
preserving every other key. If the file is invalid JSON, don't
touch it; just tell the user it should be cleaned up by hand.
2. Shell profiles: run
`fish -c 'set -U' 2>/dev/null | grep -i jira` and
`grep -l JIRA_API_TOKEN ~/.config/fish/config.fish ~/.config/fish/conf.d/*.fish ~/.zshrc ~/.bashrc ~/.zprofile ~/.profile 2>/dev/null`.
If anything turns up, tell the user (Italian) to remove it so it
can't shadow the netrc (fish: `set -e JIRA_EMAIL; set -e
JIRA_API_TOKEN`; altrimenti togliere gli `export` dal file
indicato).
## Step 4 — Report
In Italian: token verificato e salvato in `~/.config/gw-triage/netrc`.
Vale da subito, anche nelle sessioni già aperte. Per sostituirlo o dopo
una revoca basta rilanciare il setup: `/gw-triage:setup` su Claude
Code, `$setup` su Codex.
````
- [ ] **Step 2: Verify the file**
Run:
```bash
head -4 skills/setup/SKILL.md
grep -c 'netrc-file' skills/setup/SKILL.md
grep -n 'settings.json' skills/setup/SKILL.md
```
Expected: frontmatter intact with `name: setup`; `netrc-file` appears ≥1 time; `settings.json` appears only in migration/cleanup contexts (Step 0.2 and Step 3.1), never as the store.
- [ ] **Step 3: Commit**
```bash
git add skills/setup/SKILL.md
git commit -m "feat(setup): store credentials in shared netrc, migrate legacy env vars"
```
---
### Task 3: Rewrite `skills/triage/SKILL.md` with MCP/REST dual mode
**Files:**
- Modify: `skills/triage/SKILL.md` (full rewrite; frontmatter `name` unchanged)
**Interfaces:**
- Consumes: `~/.config/gw-triage/netrc` (Task 2 format) for REST mode and attachments.
- Produces: nothing consumed by other tasks; README (Task 5) references `$triage` invocation on Codex.
- [ ] **Step 1: Replace the file content**
Write `skills/triage/SKILL.md` with exactly:
````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 /gw-triage:triage, $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.
## Environment
- **Root**: `${CLAUDE_PLUGIN_ROOT}` if that variable is set; otherwise
the real path of this skill's own directory (resolve symlinks, e.g.
with `realpath`), two levels up. `config/` and `knowledge/` below
are relative to this root.
- **Netrc**: `~/.config/gw-triage/netrc` — Jira credentials, written
by the `setup` skill.
- **Mode** — how Jira is reached:
- **MCP mode** (Claude Code): the Atlassian MCP tools (prefix
`mcp__plugin_atlassian_atlassian__`) are available. 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`
- **REST mode** (Codex, or any platform without those tools): curl
against the Jira Cloud REST API v2, authenticated with
`--netrc-file ~/.config/gw-triage/netrc`. `<site>` in the URLs
below is the `site` value from routing.json; `cloudId` is not
used in REST mode.
Exception: on Claude Code (recognizable by `CLAUDE_PLUGIN_ROOT`
being set), MCP is the intended path — if the tools are missing, do
NOT fall back to REST; stop with the install guide in Step 0.
For REST calls that send a JSON body, write the body to a temp file
first (`mktemp`) and pass it with `-d @<file>` — never inline JSON
with user text on the command line.
## Step 0 — Preflight
**MCP mode**
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 `/gw-triage:triage`
2. Attachment credentials:
`test -r ~/.config/gw-triage/netrc && echo netrc || (test -n "$JIRA_EMAIL" && test -n "$JIRA_API_TOKEN" && echo env || echo missing)`.
Remember the answer for Step 7. If `missing`, tell the user
(Italian) the screenshot cannot be attached automatically and that
`/gw-triage:setup` configures it in a couple of minutes. Say it
once and proceed.
**REST mode** — the netrc is required; it is the only transport.
1. `test -r ~/.config/gw-triage/netrc && echo ok || echo missing` —
if `missing`, STOP and print in Italian: serve il token API Jira;
esegui `$setup` e poi rilancia `$triage`.
2. Verify:
curl -s -o /dev/null -w "%{http_code}" \
--netrc-file ~/.config/gw-triage/netrc \
<site>/rest/api/2/myself
Anything but `200` → STOP (Italian): token scaduto o revocato,
rilancia `$setup`.
## 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 `<root>/config/routing.json` and every `.md` file in
`<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.
If no knowledge profile covers the symptoms, classify using the
routing.json area list alone and state the lower confidence explicitly
in the draft.
## Step 4 — Duplicate check
Extract 24 distinctive keywords (include Italian and English variants
of domain terms). Search with JQL
`project = <projectKey> AND text ~ "<keywords>" AND statusCategory != Done ORDER BY created DESC`
(maxResults 10):
- MCP mode: `searchJiraIssuesUsingJql`.
- REST mode (note: search is the one call NOT on v2 — Atlassian
removed `/rest/api/2/search` in 2025; `/rest/api/3/search/jql` is
its replacement):
curl -s --netrc-file ~/.config/gw-triage/netrc -G \
--data-urlencode 'jql=<the JQL above>' \
--data-urlencode 'maxResults=10' \
--data-urlencode 'fields=summary,status,issuetype' \
"<site>/rest/api/3/search/jql"
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, add a comment with the new report's details (and note the
screenshot can't be attached to a comment automatically), report the
link, stop:
- MCP mode: `addCommentToJiraIssue`.
- REST mode — write `{"body": "<comment text>"}` to a temp file, then:
curl -s -o /tmp/gw-triage-comment.json -w "%{http_code}" \
--netrc-file ~/.config/gw-triage/netrc \
-H "Content-Type: application/json" \
-X POST -d @<temp-file> \
"<site>/rest/api/2/issue/<KEY>/comment"
Success = HTTP 201.
## 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
- MCP mode: call `createJiraIssue` with `cloudId`, `projectKey`,
`issueTypeName` (`Bug` or `Task`), `summary`, `description`, the
area's `assignee.accountId`, and
`additional_fields: {"parent": {"key": "<area epic>"}}`.
- REST mode — write this JSON to a temp file (description as plain
text; Jira wiki markup like `h3.` headings and `*bold*` is allowed):
{
"fields": {
"project": {"key": "<projectKey>"},
"issuetype": {"name": "<Bug|Task>"},
"summary": "<titolo>",
"description": "<descrizione>",
"assignee": {"accountId": "<area accountId>"},
"parent": {"key": "<area epic>"}
}
}
Then:
curl -s -o /tmp/gw-triage-create.json -w "%{http_code}" \
--netrc-file ~/.config/gw-triage/netrc \
-H "Content-Type: application/json" \
-X POST -d @<temp-file> \
"<site>/rest/api/2/issue"
Success = HTTP 201; the issue key is in the response file.
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 credentials (netrc or legacy env) 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" \
--netrc-file ~/.config/gw-triage/netrc \
-F "file=@<screenshot-path>" \
"<site>/rest/api/3/issue/<ISSUE-KEY>/attachments"
If Step 0 answered `env` (legacy install, no netrc), replace the
`--netrc-file` line with `-u "$JIRA_EMAIL:$JIRA_API_TOKEN"`, leaving
the `$` references unexpanded for the shell — never substitute the
values yourself.
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 the file**
Run:
```bash
head -4 skills/triage/SKILL.md
grep -c 'REST mode' skills/triage/SKILL.md
grep -n 'CLAUDE_PLUGIN_ROOT' skills/triage/SKILL.md
grep -n 'rest/api/3' skills/triage/SKILL.md
```
Expected: frontmatter intact with `name: triage`; `REST mode` appears in Environment and Steps 0/4/6; `CLAUDE_PLUGIN_ROOT` appears only in the Environment root/mode rules (not as a hardcoded path elsewhere); the only v3 URLs are the attachments endpoint and `search/jql`.
- [ ] **Step 3: Commit**
```bash
git add skills/triage/SKILL.md
git commit -m "feat(triage): dual MCP/REST mode with shared netrc credentials"
```
---
### Task 4: Update `skills/map-repo/SKILL.md`
**Files:**
- Modify: `skills/map-repo/SKILL.md` (three targeted edits)
**Interfaces:**
- Consumes: root-resolution convention from Tasks 23 (same preamble wording).
- [ ] **Step 1: Update frontmatter description**
Replace:
```
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".
```
with:
```
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 /gw-triage:map-repo, $map-repo, "mappa questo repo", "aggiorna il profilo di triage".
```
- [ ] **Step 2: Add the Environment section and fix root references**
After the paragraph ending "(it is read by the triage model, not by humans).", insert:
```markdown
## Environment
**Root**: `${CLAUDE_PLUGIN_ROOT}` if that variable is set; otherwise
the real path of this skill's own directory (resolve symlinks, e.g.
with `realpath`), two levels up. Paths below marked `<root>` are
relative to it.
```
Then replace `${CLAUDE_PLUGIN_ROOT}/knowledge/README.md` with `<root>/knowledge/README.md` (Step 2) and `${CLAUDE_PLUGIN_ROOT}` with `<root>` in Step 4's remote-URL instruction.
- [ ] **Step 3: Make the survey subagent optional**
Replace:
```
Dispatch ONE exploration subagent with this prompt, filling <repo-path>:
```
with:
```
If the platform supports dispatching subagents, dispatch ONE
exploration subagent with the prompt below, filling <repo-path>;
otherwise perform the same survey yourself, covering all six points
before writing anything:
```
- [ ] **Step 4: Mention the Codex update path in Step 4 of the skill**
Replace:
```
4. Tell the user (Italian) that teammates receive the update with
`/plugin marketplace update gw-triage`.
```
with:
```
4. Tell the user (Italian) that teammates receive the update with
`/plugin marketplace update gw-triage` on Claude Code, or with
`git pull` in their gw-triage clone on Codex.
```
- [ ] **Step 5: Verify and commit**
```bash
grep -c 'CLAUDE_PLUGIN_ROOT' skills/map-repo/SKILL.md
grep -n '<root>' skills/map-repo/SKILL.md
git add skills/map-repo/SKILL.md
git commit -m "feat(map-repo): platform-neutral root resolution and survey"
```
Expected: `CLAUDE_PLUGIN_ROOT` count is 1 (the Environment section only); `<root>` appears in Steps 2 and 4.
---
### Task 5: README + version bump
**Files:**
- Modify: `README.md`
- Modify: `.claude-plugin/plugin.json` (version `0.2.0` → `0.3.0`)
**Interfaces:**
- Consumes: `./install-codex.sh` (Task 1), netrc store (Task 2), `$triage`/`$setup` invocations (Tasks 23).
- [ ] **Step 1: Restructure the installation section**
Replace the `## Installazione (una volta sola)` section with:
```markdown
## Installazione (una volta sola)
### Claude Code
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 https://git.growingway.com/giuse/gw-triage.git`
`/plugin install gw-triage`
4. **Token API** (per allegare gli screenshot — facoltativo ma
consigliato): esegui `/gw-triage:setup` e segui le istruzioni.
### Codex CLI
1. Clona il repo dove preferisci:
`git clone https://git.growingway.com/giuse/gw-triage.git`
2. Dalla cartella clonata esegui `./install-codex.sh` — crea i link
alle skill in `~/.agents/skills/`. Nota: le skill si chiamano
`triage`, `setup` e `map-repo`; se hai già altre skill con questi
nomi entrano in conflitto.
3. **Token API** (qui obbligatorio — su Codex tutte le chiamate Jira
lo usano): invoca `$setup` e segui le istruzioni.
Per aggiornare: `git pull` nella cartella clonata (i link restano
validi). Su Claude Code: `/plugin marketplace update gw-triage`.
```
- [ ] **Step 2: Update the token section**
Replace the `## Token API Jira` section with:
```markdown
## Token API Jira
Su Claude Code serve solo ad allegare gli screenshot alle issue (le
altre operazioni passano dall'MCP Atlassian): senza token tutto
funziona lo stesso, viene saltato solo l'allegato. Su Codex invece è
obbligatorio: tutte le chiamate Jira lo usano.
Esegui il setup (`/gw-triage:setup` su Claude Code, `$setup` su
Codex): ti guida nella creazione del token dalla pagina Atlassian, te
lo chiede, lo verifica e lo salva in `~/.config/gw-triage/netrc`
(valido da subito, senza riavviare nulla). Se avevi già configurato il
token in `~/.claude/settings.json`, il setup lo migra da solo.
⚠️ Il token agisce a tuo nome su Jira: non condividerlo. Se trapela,
revocalo da <https://id.atlassian.com/manage-profile/security/api-tokens>.
Quando scade: su Claude Code `/gw-triage:triage` continua a funzionare
(salta solo l'allegato), su Codex si ferma e ti rimanda al setup.
Rilancia il setup per sostituirlo.
```
- [ ] **Step 3: Update daily use and troubleshooting**
In `## Uso quotidiano`, change step 1 to mention both invocations:
```markdown
1. Allega uno screenshot (**trascina il file nel prompt**, così può
essere allegato alla issue) e/o scrivi una breve descrizione del
problema, sufficiente a identificarlo, poi invoca
`/gw-triage:triage` (Claude Code) o `$triage` (Codex).
```
In `## Aggiornare la conoscenza dei repo`, replace the closing sentence
about updates with:
```markdown
il profilo aggiornato viene pushato qui e gli altri lo ricevono con
`/plugin marketplace update gw-triage` (Claude Code) o `git pull`
nella cartella clonata (Codex).
```
In `## Problemi comuni`, replace the "Allegato saltato" entry and add
one Codex entry:
```markdown
- **"MCP Atlassian non disponibile"** → passi 12 dell'installazione
Claude Code.
- **"Allegato saltato"** → esegui il setup (token mancante, scaduto o
revocato).
- **Su Codex le skill non compaiono** → riesegui `./install-codex.sh`
dalla cartella clonata e controlla i link in `~/.agents/skills/`.
- **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 4: Bump the plugin version**
In `.claude-plugin/plugin.json`, change `"version": "0.2.0"` to `"version": "0.3.0"`.
- [ ] **Step 5: Verify and commit**
```bash
grep -n 'Codex' README.md | head -20
python3 -c "import json; print(json.load(open('.claude-plugin/plugin.json'))['version'])"
git add README.md .claude-plugin/plugin.json
git commit -m "docs: Codex CLI install/usage instructions; bump to 0.3.0"
```
Expected: Codex sections present; version prints `0.3.0`.
---
### Task 6: Live verification (needs the user's Jira credentials)
**Files:** none (verification only).
This task exercises the REST path for real. It creates one throwaway
issue in the OA project — get the user's OK before running, and delete
the issue afterwards.
- [ ] **Step 1: Netrc present**
If `~/.config/gw-triage/netrc` doesn't exist, run the setup skill flow
first (or migrate from `~/.claude/settings.json` per setup Step 0.2).
- [ ] **Step 2: Auth check**
```bash
curl -s -o /dev/null -w "%{http_code}" --netrc-file ~/.config/gw-triage/netrc https://growingway.atlassian.net/rest/api/2/myself
```
Expected: `200`.
- [ ] **Step 3: JQL search**
```bash
curl -s --netrc-file ~/.config/gw-triage/netrc -G \
--data-urlencode 'jql=project = OA ORDER BY created DESC' \
--data-urlencode 'maxResults=3' \
--data-urlencode 'fields=summary,status' \
"https://growingway.atlassian.net/rest/api/3/search/jql" | head -c 400
```
Expected: JSON with `issues` array.
- [ ] **Step 4: Create + comment + attach + delete a throwaway issue**
Create (body via temp file, per the skill):
```bash
printf '%s' '{"fields":{"project":{"key":"OA"},"issuetype":{"name":"Task"},"summary":"[test gw-triage] verifica REST — da cancellare","description":"Test automatico del percorso REST di gw-triage. Cancellare."}}' > /tmp/gw-test-create.json
curl -s --netrc-file ~/.config/gw-triage/netrc -H "Content-Type: application/json" -X POST -d @/tmp/gw-test-create.json "https://growingway.atlassian.net/rest/api/2/issue"
```
Expected: JSON with a `key` (e.g. `OA-123`). With that KEY:
```bash
printf '%s' '{"body":"commento di test"}' > /tmp/gw-test-comment.json
curl -s -o /dev/null -w "%{http_code}" --netrc-file ~/.config/gw-triage/netrc -H "Content-Type: application/json" -X POST -d @/tmp/gw-test-comment.json "https://growingway.atlassian.net/rest/api/2/issue/<KEY>/comment"
```
Expected: `201`. Attachment (any small local image or text file):
```bash
curl -s -o /dev/null -w "%{http_code}" -X POST -H "X-Atlassian-Token: no-check" --netrc-file ~/.config/gw-triage/netrc -F "file=@<some-file>" "https://growingway.atlassian.net/rest/api/3/issue/<KEY>/attachments"
```
Expected: `200`. Then delete:
```bash
curl -s -o /dev/null -w "%{http_code}" --netrc-file ~/.config/gw-triage/netrc -X DELETE "https://growingway.atlassian.net/rest/api/2/issue/<KEY>"
```
Expected: `204`. Clean up `/tmp/gw-test-*.json`.
- [ ] **Step 5: Codex smoke test (user-run)**
Ask the user to run, in a Codex session: `$setup` (should report the
existing token works) and `$triage` with a sample message, stopping at
the draft confirmation with "correggi: annulla". Confirm the skills
were discovered and REST preflight passed.
- [ ] **Step 6: Claude Code regression (user-run)**
`/gw-triage:triage` with a sample report in a Claude Code session:
MCP mode preflight, netrc detected for attachments. Cancel at the
draft. Then push everything:
```bash
git push
```