From 6525f60f86823bf4b863fc1c6a4e0ab653787c17 Mon Sep 17 00:00:00 2001 From: Murphy Freelance <70611945+murphy-freelance@users.noreply.github.com> Date: Fri, 10 Jul 2026 19:27:48 +0200 Subject: [PATCH] feat(setup): store credentials in shared netrc, migrate legacy env vars Co-Authored-By: Claude Fable 5 --- skills/setup/SKILL.md | 147 +++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 72 deletions(-) diff --git a/skills/setup/SKILL.md b/skills/setup/SKILL.md index 72e9387..72632ce 100644 --- a/skills/setup/SKILL.md +++ b/skills/setup/SKILL.md @@ -1,60 +1,62 @@ --- 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 JIRA_EMAIL/JIRA_API_TOKEN, or replacing a revoked token. Triggers on /gw-triage:setup, "configura il token", "gli allegati non funzionano". +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 so -the `triage` skill can attach screenshots to issues. +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. -The only consumer of the token is the `triage` skill (its curl -attachment call), which runs inside Claude Code. Credentials therefore -go in the `env` block of `~/.claude/settings.json` — Claude Code -injects them into every session, regardless of the user's shell. Never -touch shell profiles. +## 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 `/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. Shell variables may be passed as unexpanded `$VAR` references; -literal values (pasted or read from a file) go through the temp netrc -file described in Step 0.3. +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:///rest/api/2/myself ## Step 0 — Check existing configuration -1. Run `test -n "$JIRA_EMAIL" && test -n "$JIRA_API_TOKEN" && echo session || echo unset`. -2. Read `~/.claude/settings.json` (if it exists) and note whether - `env.JIRA_EMAIL` / `env.JIRA_API_TOKEN` are present. -3. If credentials exist in either place, verify them. The check call is - - curl -s -o /dev/null -w "%{http_code}" \ - \ - https://growingway.atlassian.net/rest/api/3/myself - - (host = the `site` in `${CLAUDE_PLUGIN_ROOT}/config/routing.json`, - without the scheme). For ``: - - session env vars set → `-u "$JIRA_EMAIL:$JIRA_API_TOKEN"`, with the - `$` references left unexpanded for the shell to fill in — never - substitute the values yourself. - - literal values (from settings.json or a paste) → use the Write - tool to create a netrc file in the session scratchpad directory: - - machine growingway.atlassian.net - login - password - - `chmod 600` it and pass `--netrc-file ` instead of `-u`. - Delete this file before the skill ends, whatever the outcome. - - Result: +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. + (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) @@ -67,52 +69,53 @@ Print in Italian, compactly: 3. Incolla qui email aziendale e token (vanno bene anche su due righe). Add one line: il token verrà salvato in chiaro in -`~/.claude/settings.json` sul suo computer, quindi non condividere né il -file né questa conversazione. +`~/.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 — Verify before saving +## Step 2 — Save, then verify -Run the Step 0.3 check with the pasted values — literals, so via the -temp netrc file, never `-u` on the command line. +1. Create `~/.config/gw-triage/` if missing. Write the netrc file with + the file-writing tool: -- `200` → proceed to 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, - then verify again; stop after the third failed verification overall - and suggest creating a fresh token. -- Anything else (timeout, DNS) → network problem, not credentials: - report it and stop; the pasted token stays valid for a later retry. + machine + login + password -## Step 3 — Save to settings.json + 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. -Update `~/.claude/settings.json` with Read + Edit/Write (never shell -text-mangling): +## Step 3 — Clean up legacy stores -- File missing → create it containing only - `{"env": {"JIRA_EMAIL": "", "JIRA_API_TOKEN": ""}}`. -- Valid JSON → add or overwrite the two keys inside the existing `env` - object (create the object if absent). Preserve every other key - untouched. -- Invalid JSON → do NOT overwrite; show the user the parse error and - stop. - -Leftover check: old installs configured the shell profile instead. 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 new token (fish: `set -e JIRA_EMAIL; set -e JIRA_API_TOKEN`; -altrimenti togliere gli `export` dal file indicato). +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 -Delete the temp netrc file if one was created. - -In Italian: token verificato e salvato. Vale dalle **prossime** sessioni -di Claude Code — quelle già aperte vanno riavviate prima che l'allegato -automatico funzioni. Per sostituirlo o dopo una revoca basta rilanciare -`/gw-triage:setup`. +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.