Files
gw-triage/docs/codex-support-design.md

173 lines
6.9 KiB
Markdown

# gw-triage — Codex CLI support
Date: 2026-07-10
Status: approved
## Problem
The plugin only runs under Claude Code: distribution relies on the
Claude plugin marketplace, skills locate their data via
`${CLAUDE_PLUGIN_ROOT}`, Jira access goes through the Atlassian MCP
plugin, and credentials live in the `env` block of
`~/.claude/settings.json`. Teammates on OpenAI Codex CLI can't use any
of it. Goal: full parity — `triage`, `setup`, and `map-repo` all work
on Codex, from the same repo, with no duplicated skill files.
## Decisions (agreed 2026-07-10)
1. **Scope**: full parity for all three skills.
2. **Jira transport on Codex**: plain REST via curl with the Jira API
token. No MCP configuration on Codex. Claude Code keeps its MCP
path unchanged.
3. **Skill files**: one SKILL.md per skill, shared by both platforms,
branching internally where behavior differs.
4. **Credentials**: a single netrc file at `~/.config/gw-triage/netrc`
used by curl on both platforms, replacing the settings.json env
block as the primary store.
## Verified platform facts
- Codex discovers skills in `.agents/skills` (project, walking up to
repo root) and `~/.agents/skills` (user level). Symlinked skill
directories are followed.
- Skills use the same SKILL.md format (frontmatter `name` +
`description`); invoked explicitly as `$<name>` or implicitly via
the description.
- Codex's `[shell_environment_policy]` env injection filters names
containing `TOKEN` by default and has open reliability issues —
ruled out in favor of the netrc file.
- Jira Cloud REST API v2 (`/rest/api/2/…`) is still served and accepts
plain-text descriptions, avoiding the ADF JSON required by v3
`createIssue`. v2 is legacy; if Atlassian retires it, the REST-mode
steps move to v3 + minimal ADF paragraphs.
## Design
### 1. Distribution
Repo structure unchanged. Codex users clone the repo anywhere and
symlink each skill directory into `~/.agents/skills/`:
~/.agents/skills/triage -> <clone>/skills/triage
~/.agents/skills/setup -> <clone>/skills/setup
~/.agents/skills/map-repo -> <clone>/skills/map-repo
A small `install-codex.sh` at the repo root creates/refreshes the
symlinks idempotently. Updates arrive with `git pull` in the clone.
Skill names stay as-is so Claude Code commands don't change
(`/gw-triage:triage`). On Codex they are `$triage`, `$setup`,
`$map-repo`; the generic names could collide with other installed
skills — accepted risk for a three-person team, noted in the README.
### 2. Platform detection and root resolution
Each SKILL.md gets a short "Environment" preamble:
- **Root**: `${CLAUDE_PLUGIN_ROOT}` if set; otherwise resolve the real
path (symlinks followed) of the skill's own directory and go up two
levels. `config/` and `knowledge/` are addressed relative to that
root everywhere.
- **Mode** (triage only): Atlassian MCP tools available → MCP mode
(today's behavior, unchanged); otherwise → REST mode.
### 3. Credentials — netrc file
`setup` writes `~/.config/gw-triage/netrc`:
machine growingway.atlassian.net
login <email>
password <token>
(machine host derived from `site` in routing.json), `chmod 600`. Every
curl call on both platforms passes `--netrc-file
~/.config/gw-triage/netrc`, read at call time — no session restart
needed after setup, and no secrets on command lines or in process
listings.
`setup` itself becomes platform-neutral (file operations + curl only):
- Verify pasted credentials against `GET /rest/api/2/myself` before
saving (3-attempt limit, network-vs-auth error distinction — as
today).
- **Migration**: if credentials already exist in the session env or in
`~/.claude/settings.json` `env`, verify them and migrate them into
the netrc automatically; suggest removing the settings.json entries
(leftover shell-profile check stays).
- The temp-netrc-for-literals dance disappears: the real netrc file IS
the store, written before verification and deleted only if
verification ultimately fails.
`triage` reads the netrc as the primary credential source and falls
back to `JIRA_EMAIL`/`JIRA_API_TOKEN` env vars (legacy installs) for
the attachment step.
### 4. Triage in REST mode
Used on Codex. (Claude Code without MCP still stops and points at the
Atlassian plugin install, as today — MCP remains the intended path
there.)
On Codex the token is **required** — it is the only transport. Missing
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/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` |
`cloudId` in routing.json becomes MCP-only; REST mode uses `site`.
Classification, drafting, confirmation flow, and Italian interaction
are identical in both modes.
### 5. map-repo
Two touch-ups:
- Root resolution per §2 (replaces `${CLAUDE_PLUGIN_ROOT}`).
- Survey step: "dispatch one exploration subagent **if the platform
supports subagent dispatch; otherwise perform the survey yourself**,
covering the same six points."
- Publish step: note that Codex teammates receive updates with
`git pull` in their clone (Claude Code users keep
`/plugin marketplace update gw-triage`).
### 6. README
- New "Installazione (Codex)" section: clone, `./install-codex.sh`,
run `$setup`, daily use via `$triage`.
- Token section updated: netrc path, token optional on Claude Code
(attachments only), **required** on Codex.
- Per-platform update instructions and troubleshooting entries.
## Error handling
- REST calls: treat non-2xx as failure; show the raw body with a
one-line Italian summary. Create-issue failure stops before the
attachment step (nothing partial), as today.
- Netrc unreadable/missing on Codex → stop with setup guidance; on
Claude Code → warn once that attachment will be skipped, proceed.
- JQL must be URL-encoded in REST mode (curl `--data-urlencode` with
`-G`).
## Testing
- REST commands exercised directly against Jira: `myself`, JQL search,
create on a throwaway issue, comment, attachment — then delete the
throwaway.
- Codex smoke test: skills discovered after `install-codex.sh`,
`$triage` dry run reaches the draft step, `$setup` full run.
- Claude Code regression: `/gw-triage:triage` full run with netrc in
place (MCP mode + netrc attachment), `/gw-triage:setup` migration
path from settings.json env vars.
## Out of scope
- Renaming skills or namespacing for Codex.
- Moving Claude Code off MCP.
- Windows support (team is on macOS).
- v3/ADF migration (documented as future work if v2 is retired).