$npx -y skills add opendatahub-io/ai-helpers --skill doc-gatherUse when you need to gather context for a Jira ticket or PR. Resolves ticket metadata, clones relevant repos, collects candidate files, runs filtering pipeline, and produces workspace/context-package.json.
| 1 | # doc-gather |
| 2 | |
| 3 | Gather context from Jira tickets, source repos, and documentation repos to produce a structured context package for downstream skills. |
| 4 | |
| 5 | ## Parse arguments |
| 6 | |
| 7 | `$ARGUMENTS` contains either: |
| 8 | - A Jira ticket key (e.g., `RHOAIENG-55490`) |
| 9 | - A PR/MR URL (e.g., `https://github.com/org/repo/pull/123`) |
| 10 | |
| 11 | Detect the input type: |
| 12 | - If it starts with `http` → PR URL |
| 13 | - Otherwise → Jira ticket key |
| 14 | |
| 15 | ## Step 1: Resolve ticket metadata |
| 16 | |
| 17 | ### For Jira tickets |
| 18 | |
| 19 | Use the resolve script to fetch and structure ticket metadata: |
| 20 | |
| 21 | ```bash |
| 22 | bash ${CLAUDE_SKILL_DIR}/scripts/resolve-jira.sh <JIRA-KEY> |
| 23 | ``` |
| 24 | |
| 25 | This returns JSON with: `key`, `summary`, `description`, `acceptance_criteria`, `fix_versions`, `components`, `linked_tickets`, `epic_key`, `status`, `issue_type`. |
| 26 | |
| 27 | If the ticket has linked tickets that provide useful context (e.g., parent epic, related stories), resolve those too (up to 5 linked tickets): |
| 28 | |
| 29 | ```bash |
| 30 | bash ${CLAUDE_SKILL_DIR}/scripts/resolve-jira.sh <LINKED-KEY> |
| 31 | ``` |
| 32 | |
| 33 | ### For PR URLs |
| 34 | |
| 35 | Use `gh` CLI to extract PR metadata: |
| 36 | |
| 37 | ```bash |
| 38 | gh pr view <PR-URL> --json title,body,labels,files,headRefName |
| 39 | ``` |
| 40 | |
| 41 | Extract the Jira key from the PR title or body (pattern: `[A-Z]+-\d+`), then resolve the Jira ticket using the resolve script as above. |
| 42 | |
| 43 | ## Step 2: Parse product configuration |
| 44 | |
| 45 | Read the product configuration bundled with this skill: |
| 46 | |
| 47 | ```bash |
| 48 | python3 ${CLAUDE_SKILL_DIR}/scripts/parse-product-config.py ${CLAUDE_SKILL_DIR}/references/rhoai.yaml |
| 49 | ``` |
| 50 | |
| 51 | From the config, determine: |
| 52 | 1. **Context sources** — which repos to clone and where to find files |
| 53 | 2. **Version mappings** — how to map Jira fixVersion to git branches |
| 54 | 3. **Component resolver** — map Jira component names to repo slugs |
| 55 | 4. **Docs conventions** — module prefixes, framework, attribute files |
| 56 | |
| 57 | ## Step 3: Resolve version to branches |
| 58 | |
| 59 | For each fixVersion from the ticket: |
| 60 | |
| 61 | ```bash |
| 62 | python3 ${CLAUDE_SKILL_DIR}/scripts/parse-product-config.py ${CLAUDE_SKILL_DIR}/references/rhoai.yaml --resolve-version "<fixVersion>" |
| 63 | ``` |
| 64 | |
| 65 | This determines which branch to checkout for each repo. |
| 66 | |
| 67 | ## Step 4: Resolve components to repos |
| 68 | |
| 69 | For each component from the ticket: |
| 70 | |
| 71 | ```bash |
| 72 | python3 ${CLAUDE_SKILL_DIR}/scripts/parse-product-config.py ${CLAUDE_SKILL_DIR}/references/rhoai.yaml --resolve-component "<component-name>" |
| 73 | ``` |
| 74 | |
| 75 | This identifies which source repos are relevant. |
| 76 | |
| 77 | ## Step 5: Clone and collect candidate files |
| 78 | |
| 79 | For each context source in the product config, plus each resolved component repo: |
| 80 | |
| 81 | ```bash |
| 82 | bash ${CLAUDE_SKILL_DIR}/scripts/gather-context.sh <repo-slug> <branch> <path-patterns...> |
| 83 | ``` |
| 84 | |
| 85 | The branch is determined by: |
| 86 | 1. Version resolution from Step 3 (if applicable) |
| 87 | 2. The `branch_hint` from the context source declaration |
| 88 | 3. Fallback to `main` |
| 89 | |
| 90 | ## Step 6: Run filtering pipeline |
| 91 | |
| 92 | Assemble a JSON input for the filtering pipeline combining: |
| 93 | - All candidate files from Step 5 |
| 94 | - Task context (ticket metadata as keywords, components, version) |
| 95 | - Source declarations from product config |
| 96 | |
| 97 | ```bash |
| 98 | python3 ${CLAUDE_SKILL_DIR}/scripts/context-filter.py <<< '<assembled-json>' |
| 99 | ``` |
| 100 | |
| 101 | The pipeline runs six stages: |
| 102 | 1. **Static inclusion** — mark always_include sources |
| 103 | 2. **Version branch** — (already resolved in Step 3) |
| 104 | 3. **Component affinity** — filter by component overlap |
| 105 | 4. **Path relevance** — score by path patterns and keywords |
| 106 | 5. **Keyword relevance** — BM25 scoring against ticket text |
| 107 | 6. **Budget enforcement** — select top candidates within 100K token budget |
| 108 | |
| 109 | ## Step 7: Read file contents |
| 110 | |
| 111 | Source the git utilities (which internally uses `scripts/load-env.sh` to load credentials from the environment) and read each selected candidate's content from the cloned repo: |
| 112 | |
| 113 | ```bash |
| 114 | source ${CLAUDE_SKILL_DIR}/scripts/git-utils.sh |
| 115 | git_file_content "workspace/repos/<repo-slug>" "<file-path>" |
| 116 | ``` |
| 117 | |
| 118 | Attach content to each candidate entry. |
| 119 | |
| 120 | ## Step 8: Write context package |
| 121 | |
| 122 | Write `workspace/context-package.json` with this structure: |
| 123 | |
| 124 | ```json |
| 125 | { |
| 126 | "ticket": { |
| 127 | "key": "RHOAIENG-55490", |
| 128 | "summary": "...", |
| 129 | "description": "...", |
| 130 | "fix_versions": ["rhoai-2.18"], |
| 131 | "components": ["Dashboard"], |
| 132 | "linked_tickets": [], |
| 133 | "epic_key": "", |
| 134 | "status": "In Progress", |
| 135 | "issue_type": "Story" |
| 136 | }, |
| 137 | "product": { |
| 138 | "product_id": "rhoai", |
| 139 | "display_name": "Red Hat OpenShift AI", |
| 140 | "docs_repo": "opendatahub-io/opendatahub-documentation", |
| 141 | "docs_branch": "main", |
| 142 | "framework": "asciidoc-modular", |
| 143 | "module_prefixes": { |
| 144 | "concept": "con_", |
| 145 | "procedure": "proc_", |
| 146 | "reference": "ref_", |
| 147 | "assembly": "assembly_", |
| 148 | "snippet": "snip_" |
| 149 | } |
| 150 | }, |
| 151 | "context |