Files
gw-triage/docs/codex-support-design.md
Murphy Freelance a967f5c38e docs: design for Codex CLI support
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 19:16:19 +02:00

6.9 KiB

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 offer to migrate them into the netrc; 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/2/search?jql=<urlencoded>
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).