Skip to content

Move and upgrade dotcms-github-issues Claude skill into project repository #34800

@spbolton

Description

@spbolton

Description

The project previously shipped a basic create-issue Claude Code skill at .claude/skills/create-issue/ (added in #34465). This was a 232-line, CREATE-only workflow with significant gaps:

  • No team caching — always prompted for team assignment
  • Feature label defaulted to dotCMS : Content Management when no match was found
  • Did not set the native GitHub Issue Type after creation
  • Did not set Project testing assign #7 Technology field via GraphQL
  • Did not support sub-issues, relationships, or any query/update operations

Over multiple sessions the skill has been substantially reworked into a multi-mode AI-agent-native skill called dotcms-github-issues. The new skill (589 lines + 3 reference files) currently lives at the user level (~/.claude/skills/dotcms-github-issues/) for testing. This task is to move it into the project repository and ship the accompanying slash command stubs.

What changed vs the original skill

Capability Old create-issue (232 lines) New dotcms-github-issues (589 lines)
Modes CREATE only CREATE · UPDATE · QUERY · FIND
Team assignment Always prompted Cached default; asks only when no cache
Native GitHub Issue Type Not set Set via REST PATCH immediately after creation
Project #7 Technology field Not set Set via GraphQL mutation
Sub-issues / relationships Not supported Sub-issue REST endpoint + cross-reference comments
Feature label fallback Defaulted to dotCMS : Content Management Asks when ambiguous; no incorrect default applied
Sprint / iteration queries Not supported Full per-team sprint awareness — current and historical (see below)
Reference files feature-labels.md only feature-labels.md · github-apis.md · project-fields.md
Team selection UX Single flat prompt Cascading Stage 1 / Stage 2 + free-text fallback
Type : label Not applied Derived from template + description keywords
UPDATE mode Fetches state, shows validation table, applies changes
QUERY mode Returns title, labels, native type, project fields, sub-issues
FIND mode Sprint/backlog queries per team with velocity summary

Sprint and iteration awareness (FIND mode)

The FIND mode can answer "what is the team working on this sprint?" and "what did the team complete last sprint?" for any sprint-based team. This required solving several non-obvious problems.

Per-team iteration fields

Each sprint team has a dedicated ProjectV2IterationField ID in Project #7 — separate from the shared Status and Technology fields. These IDs are catalogued in references/project-fields.md:

Team Sprint field ID
Falcon PVTIF_lADOAA9Wz84AKDq_zgcwTUQ
Maintenance PVTIF_lADOAA9Wz84AKDq_zgIGutk
Scout PVTIF_lADOAA9Wz84AKDq_zgdo3T0
Platform PVTIF_lADOAA9Wz84AKDq_zgj83DM

Kanban-only teams (Enablement, Modernization, UX) have no iteration field. The skill detects this and falls back to Status-field queries automatically.

Querying current and previous sprints

To find the active sprint title, the skill queries the team's iteration field for its iterations (active) list. To find the previous sprint, it queries completedIterations on the same field and selects the most recent entry by startDate. Both lookups use GraphQL against Project #7 directly — no hardcoded sprint names.

Once the sprint title is known, issues are filtered by matching the iterationValue.title field value on each issue's project item.

Critical pagination fix

The naive approach of querying node(id: projectId).items(first: 100) returns the oldest 100 project items — for a team like Scout with 1,600+ issues, recently closed sprint items are completely absent. The same problem affects gh issue list: it returns the oldest 100 by default regardless of label filter.

The fix uses repository.issues with orderBy: {field: UPDATED_AT, direction: DESC} and states: [OPEN, CLOSED], ensuring recently-updated issues (including Done items closed during the sprint) appear at the top of the result set within the 100-item cursor window. This was validated against Scout Sprint 4 (Feb 11–24, 2026) which had 5 Done items — all 5 were returned correctly after the fix.

jq reliability

Two silent failure modes were discovered and documented:

  • The != operator is shell-expanded in bash heredoc jq expressions; use chained select() calls instead
  • Reusing an --arg name (e.g. --arg sprint) as an internal as $sprint binding causes a silent variable collision; use a distinct internal name (e.g. as $iterTitle)

Null-safety is also required: when a project item exists but has no iteration value, .fieldValues.nodes[] must be guarded with // [] to avoid a runtime error.

Slash commands

Four command stubs in .claude/commands/ route to the correct mode — already added in this session:

Command Mode
/create-issue CREATE
/update-issue UPDATE
/query-issue QUERY
/find-issues FIND

Acceptance Criteria

  • dotcms-github-issues/ skill directory (SKILL.md + all three reference files) moved into .claude/skills/ in the project repo
  • .claude/commands/ directory contains all four command stubs: create-issue.md, update-issue.md, query-issue.md, find-issues.md
  • Old .claude/skills/create-issue/ directory confirmed removed
  • CREATE mode verified: issue created with correct labels, native type set, Technology field set in Project testing assign #7
  • UPDATE mode verified: fetches current state, shows validation table, applies changes
  • QUERY mode verified: returns title, labels, native type, project fields, sub-issues
  • FIND mode verified: current sprint query and previous sprint query both return correct results for a sprint team (e.g. Scout)
  • FIND mode verified: kanban team query (e.g. Enablement) falls back to Status-based results correctly
  • All four commands tested in a fresh Claude Code session from the project directory

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions