Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ jobs:
- name: Build and smoke-test the standalone rhdh CLI
run: |
uv build
python -m venv /tmp/rhdh-skill-wheel
/tmp/rhdh-skill-wheel/bin/pip install dist/*.whl
/tmp/rhdh-skill-wheel/bin/rhdh --help
/tmp/rhdh-skill-wheel/bin/rhdh-local --help
/tmp/rhdh-skill-wheel/bin/rhdh local --help
python -m venv /tmp/rhdh-skills-wheel
/tmp/rhdh-skills-wheel/bin/pip install dist/*.whl
/tmp/rhdh-skills-wheel/bin/rhdh --help
/tmp/rhdh-skills-wheel/bin/rhdh-local --help
/tmp/rhdh-skills-wheel/bin/rhdh local --help
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ that preserve the skill interface.
Changes to skill layout must retain established runtime locations unless an ADR
explicitly changes them:

- `~/.config/rhdh-skill/config.json`
- `~/.config/rhdh-skills/config.json`
- `.rhdh/worklog.jsonl`
- `.rhdh/TODO.md`

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Install the pack and the three external skills it depends on. Each command opens
the skills wizard, which asks where to put them:

```bash
npx skills add redhat-developer/rhdh-skill --all
npx skills add redhat-developer/rhdh-skills --all
npx skills add mattpocock/skills --skill grilling
npx skills add mattpocock/skills --skill handoff
npx skills add blader/humanizer
Expand Down Expand Up @@ -108,7 +108,7 @@ See [ADR-0005](docs/adr/0005-one-skill-per-trigger-phrase.md),
## CLI and state

- `rhdh` and `rhdh-local` are bundled wrappers, run from their skill directory.
- Repository configuration lives at `~/.config/rhdh-skill/config.json`.
- Repository configuration lives at `~/.config/rhdh-skills/config.json`.
- Worklog and todo state lives under `.rhdh/`.
- Cross-session handoff is not a pack feature; run `/handoff` when you need it.

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0005-one-skill-per-trigger-phrase.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ or reads its private files. Human-invoked skills are entry points for people and
are never invoked by a model-invoked skill.

Setup preserves the existing `rhdh` and `rhdh-local` CLI behaviour,
`~/.config/rhdh-skill/config.json`, and worklog and todo locations.
`~/.config/rhdh-skills/config.json`, and worklog and todo locations.
`/setup-rhdh-skills` is the exclusive human setup router; a domain skill may detect
a missing capability and name the setup command, but never installs, authenticates,
or probes host skill directories itself.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[project]
name = "rhdh-skill"
name = "rhdh-skills"
version = "0.0.0"
description = "Composable agent skills for Red Hat Developer Hub development and operations"
readme = "README.md"
Expand Down
2 changes: 1 addition & 1 deletion skills/ci/rhdh-base-images/workflows/update-base-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Verify the target branch exists in each repo before running.
**Execute** [scripts/base-images-and-rpms.sh](../scripts/base-images-and-rpms.sh); do not reimplement the workflow inline.

```bash
SKILL=/path/to/installed/rhdh-base-images # under 1-rhdh-skill checkout
SKILL=/path/to/installed/rhdh-base-images # under 1-rhdh-skills checkout
chmod +x "${SKILL}/scripts/base-images-and-rpms.sh"

# All three repos under a parent directory
Expand Down
2 changes: 1 addition & 1 deletion skills/ci/rhdh-prow-jobs/scripts/analyze_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _fetch_api(product_name):
"""Fetch lifecycle data directly from the Red Hat API (fallback)."""
url = f"{LIFECYCLE_API_URL}?name={urllib.parse.quote_plus(product_name)}"
req = urllib.request.Request(
url, headers={"Accept": "application/json", "User-Agent": "rhdh-skill"}
url, headers={"Accept": "application/json", "User-Agent": "rhdh-skills"}
)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def fetch_yaml(filepath: str, root: Path | None, is_remote: bool) -> dict | None
if is_remote:
raw_url = f"https://raw.githubusercontent.com/{GITHUB_REPO}/HEAD/{filepath}"
try:
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skills"})
with urllib.request.urlopen(req, timeout=30) as resp:
return _yaml.load(resp.read().decode("utf-8"))
except (urllib.error.URLError, OSError) as exc:
Expand Down
2 changes: 1 addition & 1 deletion skills/ci/rhdh-prow-trigger/scripts/gangway_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def _request(
headers={
"Authorization": f"Bearer {self._token()}",
"Content-Type": "application/json",
"User-Agent": "rhdh-skill",
"User-Agent": "rhdh-skills",
},
method=method,
)
Expand Down
4 changes: 2 additions & 2 deletions skills/ci/rhdh-prow-trigger/scripts/trigger_nightly_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def fetch_configured_jobs(repo: str) -> list[str]:
entries. We extract job names ending in ``-nightly`` via regex.
"""
url = f"https://prow.ci.openshift.org/configured-jobs/{repo}"
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skills"})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
html = resp.read().decode("utf-8")
Expand Down Expand Up @@ -221,7 +221,7 @@ def _fetch_quay_tags(image_repo: str, like_filter: str) -> list[dict]:
f"https://quay.io/api/v1/repository/{encoded_repo}/tag/"
f"?limit=100&onlyActiveTags=true&filter_tag_name=like:{encoded_filter}"
)
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skills"})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
data = json.loads(resp.read().decode("utf-8"))
Expand Down
2 changes: 1 addition & 1 deletion skills/meta/setup-rhdh-skills/assets/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schemaVersion": 1,
"pack": {
"name": "RHDH complete",
"source": "redhat-developer/rhdh-skill",
"source": "redhat-developer/rhdh-skills",
"url": null,
"requiredExternalSkills": [
{
Expand Down
2 changes: 1 addition & 1 deletion skills/meta/setup-rhdh-skills/references/private-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The internal repository contains Jira Rich Filter exports used for release coord
1. Clone it into a user-selected workspace:

```bash
git clone git@gitlab.cee.redhat.com:rhidp/rhdh-skill-private-data.git
git clone git@gitlab.cee.redhat.com:rhidp/rhdh-skills-private-data.git
```

2. Register the resolved checkout through the `rhdh` CLI, which keeps the same key names and
Expand Down
2 changes: 1 addition & 1 deletion skills/meta/setup-rhdh-skills/references/repositories.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Configure RHDH repositories

Use `rhdh doctor --json` to inspect repository discovery. The preserved configuration precedence is
environment override, project `.rhdh/config.json`, user `~/.config/rhdh-skill/config.json`, then
environment override, project `.rhdh/config.json`, user `~/.config/rhdh-skills/config.json`, then
bounded workspace discovery.

For each missing repository:
Expand Down
2 changes: 1 addition & 1 deletion skills/meta/setup-rhdh-skills/scripts/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def setup_status(
if (project_root / ".rhdh" / "config.json").is_file()
else "missing",
"userConfiguration": "present"
if (home / ".config" / "rhdh-skill" / "config.json").is_file()
if (home / ".config" / "rhdh-skills" / "config.json").is_file()
else "missing",
},
}
Expand Down
2 changes: 1 addition & 1 deletion skills/plugins/rhdh-local/scripts/NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Original work:
Repository: https://github.com/benwilcock/rhdh-lab
License: Apache License 2.0

These scripts have been adapted and extended for use in the rhdh-skill project.
These scripts have been adapted and extended for use in the rhdh-skills project.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use these files except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion skills/plugins/rhdh-local/scripts/fetch-plugin-metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ def _parse_list(lines: list[str], idx: int, base_indent: int) -> tuple[list[Any]

def _fetch(url: str) -> bytes:
"""Fetch *url* and return the response body bytes."""
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skill/0.1"})
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skills/0.1"})
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.read()

Expand Down
12 changes: 6 additions & 6 deletions skills/reference/rhdh-context/references/rhdh-repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,9 @@ Reference of all RHDH-related repositories, what each one is used for, and how t
- **Used by overlay workflows:** `rhdh-plugin-export-overlays` can use the factory container for local plugin builds.
- **Key paths:** `Containerfile` (image definition)

### rhdh-skill-private-data
### rhdh-skills-private-data

- **Upstream:** <https://gitlab.cee.redhat.com/rhidp/rhdh-skill-private-data>
- **Upstream:** <https://gitlab.cee.redhat.com/rhidp/rhdh-skills-private-data>
- **Description:** Jira Rich Filter exports and operational data used by RHDH skills. Contains exported Rich Filter JSON from the "RHIDP Operational" Jira Rich Filter managed by Matt Reid and Jasper Chui.
- **Key concepts:**
- **Rich Filter exports:** JSON exports from Jira Rich Filters that define project-scoped queries, component exclusion lists, team Cloud ID mappings, and queue definitions. Used by the `rhdh-release-status` skill to source JQL queries at runtime instead of hardcoding them.
Expand Down Expand Up @@ -289,9 +289,9 @@ Reference of all RHDH-related repositories, what each one is used for, and how t
- **Tags:** `latest` (production), `dev` (non-PR builds), `X.Y.Z` (immutable release), `<sha>` (debugging).
- **Key paths:** `blueprints/` (infrastructure blueprints), `docs/` (GCP infrastructure and sandbox networking), plus the repository's Fullsend agent skill

### rhdh-skill
### rhdh-skills

- **Upstream:** <https://github.com/redhat-developer/rhdh-skill>
- **Upstream:** <https://github.com/redhat-developer/rhdh-skills>
- **Description:** Composable agent-skill collection for RHDH development and operations. Published via the [Agent Skills](https://agentskills.io) open standard.
- **Tech stack:** Python (stdlib-only CLIs), Bash, Claude Code skills
- **Key concepts:**
Expand All @@ -302,7 +302,7 @@ Reference of all RHDH-related repositories, what each one is used for, and how t
### rhdh-users-skill-pack

- **Upstream:** <https://github.com/redhat-developer/rhdh-users-skill-pack>
- **Description:** Agent Skills for adopting and using RHDH effectively. Aimed at RHDH end-users (vs `rhdh-skill` which targets the development team). Published via the [Agent Skills](https://agentskills.io) open standard.
- **Description:** Agent Skills for adopting and using RHDH effectively. Aimed at RHDH end-users (vs `rhdh-skills` which targets the development team). Published via the [Agent Skills](https://agentskills.io) open standard.
- **Tech stack:** Python (stdlib-only CLIs), Bash, Claude Code skills
- **Key concepts:**
- **`rhdh-templates`:** Interactive authoring and validation for RHDH Software Templates — templatize existing repos, create from scratch, fix common gotchas, validate locally or against a running instance.
Expand Down Expand Up @@ -356,7 +356,7 @@ rhdh (enterprise distribution, github.com)
| +-- rhdh-fullsend (agent sandbox images & /fullsend skill)
|
+-- Agent skills:
+-- rhdh-skill (dev team skills — overlay, lifecycle, prow, etc.)
+-- rhdh-skills (dev team skills — overlay, lifecycle, prow, etc.)
+-- rhdh-users-skill-pack (user skills — templates, upgrade helper)
```

Expand Down
2 changes: 1 addition & 1 deletion skills/reference/rhdh-context/rhdh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("rhdh-skill")
__version__ = version("rhdh-skills")
except PackageNotFoundError:
__version__ = "0.0.0"

Expand Down
2 changes: 1 addition & 1 deletion skills/reference/rhdh-context/rhdh/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ def cmd_doctor(fmt: OutputFormatter, _args: argparse.Namespace) -> int:
checks.append({"name": "data_dir", "status": "info", "message": str(data_dir)})
fmt.log_info(f"Data directory: {data_dir}")
fmt.log_info(" (worklog.jsonl, TODO.md)")
fmt.log_info(" Override with RHDH_SKILL_DATA_DIR env var")
fmt.log_info(" Override with RHDH_SKILLS_DATA_DIR env var")

# Summary
fmt.header("Summary")
Expand Down
14 changes: 7 additions & 7 deletions skills/reference/rhdh-context/rhdh/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Config locations (highest to lowest priority):
1. Environment variables (RHDH_OVERLAY_REPO, etc.)
2. Project config (.rhdh/config.json in git root)
3. User config (~/.config/rhdh/config.json)
3. User config (~/.config/rhdh-skills/config.json)
4. Auto-detection (../repo/ relative to skill install)

Supports dot-notation keys (e.g., repos.overlay, user.name).
Expand All @@ -21,11 +21,11 @@

# Config directory names
PROJECT_CONFIG_DIR_NAME = ".rhdh"
USER_CONFIG_DIR = Path.home() / ".config" / "rhdh-skill"
USER_CONFIG_DIR = Path.home() / ".config" / "rhdh-skills"
USER_CONFIG_FILE = USER_CONFIG_DIR / "config.json"

# Environment variable for data directory override
DATA_DIR_ENV_VAR = "RHDH_SKILL_DATA_DIR"
DATA_DIR_ENV_VAR = "RHDH_SKILLS_DATA_DIR"

# Submodule repository definitions
# Format: name -> {has_fork, required, config_key, description}
Expand Down Expand Up @@ -109,13 +109,13 @@
"description": "Upstream Backstage framework",
"upstream_org": "backstage",
},
"rhdh-skill-private-data": {
"rhdh-skills-private-data": {
"has_fork": False,
"required": False,
"config_key": "private-data",
"description": "Jira Rich Filter exports and operational data for RHDH skills",
"upstream_host": "gitlab.cee.redhat.com",
"upstream_path": "rhidp/rhdh-skill-private-data",
"upstream_path": "rhidp/rhdh-skills-private-data",
},
}

Expand Down Expand Up @@ -158,7 +158,7 @@ def get_data_dir() -> Path:
Always centralizes data in one location to avoid scattering
across different repos/worktrees.

Uses RHDH_DATA_DIR env var if set, otherwise ~/.config/rhdh/.
Uses RHDH_SKILLS_DATA_DIR if set, otherwise ~/.config/rhdh-skills/.
"""
env_value = os.environ.get(DATA_DIR_ENV_VAR)
if env_value:
Expand Down Expand Up @@ -305,7 +305,7 @@ def deep_merge(base: dict, override: dict) -> dict:


def load_user_config() -> dict:
"""Load user config from ~/.config/rhdh/config.json.
"""Load user config from ~/.config/rhdh-skills/config.json.

Returns:
Config dict, or empty dict if file doesn't exist.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

def fetch_text(url):
"""Fetch text content from a URL."""
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skills"})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.read().decode("utf-8")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def fetch_yaml(filepath: str, root: Path | None, is_remote: bool) -> dict | None
if is_remote:
raw_url = f"https://raw.githubusercontent.com/{GITHUB_REPO}/HEAD/{filepath}"
try:
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skills"})
with urllib.request.urlopen(req, timeout=30) as resp:
return _yaml.load(resp.read().decode("utf-8"))
except (urllib.error.URLError, OSError) as exc:
Expand All @@ -129,7 +129,7 @@ def fetch_yaml_text(filepath: str, root: Path | None, is_remote: bool) -> str |
if is_remote:
raw_url = f"https://raw.githubusercontent.com/{GITHUB_REPO}/HEAD/{filepath}"
try:
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(raw_url, headers={"User-Agent": "rhdh-skills"})
with urllib.request.urlopen(req, timeout=30) as resp:
return resp.read().decode("utf-8")
except (urllib.error.URLError, OSError) as exc:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def fetch_api(product_name):
"""
url = f"{LIFECYCLE_API_URL}?name={urllib.parse.quote_plus(product_name)}"
req = urllib.request.Request(
url, headers={"Accept": "application/json", "User-Agent": "rhdh-skill"}
url, headers={"Accept": "application/json", "User-Agent": "rhdh-skills"}
)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def fetch_json(url):

Returns the parsed JSON, or None on failure.
"""
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skill"})
req = urllib.request.Request(url, headers={"User-Agent": "rhdh-skills"})
try:
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read().decode("utf-8"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _configured_repo() -> Path | None:
if env_path and Path(env_path).is_dir():
return Path(env_path).resolve()

config_paths = [Path.home() / ".config" / "rhdh-skill" / "config.json"]
config_paths = [Path.home() / ".config" / "rhdh-skills" / "config.json"]
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _configured_repo() -> Path | None:
if env_path and Path(env_path).is_dir():
return Path(env_path).resolve()

config_paths = [Path.home() / ".config" / "rhdh-skill" / "config.json"]
config_paths = [Path.home() / ".config" / "rhdh-skills" / "config.json"]
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
Expand Down
2 changes: 1 addition & 1 deletion skills/release/rhdh-release-status/references/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Static configuration values for the RHDH Release Manager skill.

The Rich Filter JSON is sourced from the "RHIDP Operational" Rich Filter in Jira, maintained by Matt Reid and Jasper Chui. It is required for freeze, demo/Test Day, post-freeze, release-note lifecycle, Scrum Team, and exported ad hoc queries.

The repo is discovered via `rhdh.config.get_repo("private-data")`. Register it with `rhdh config set private-data /path/to/rhdh-skill-private-data`.
The repo is discovered via `rhdh.config.get_repo("private-data")`. Register it with `rhdh config set private-data /path/to/rhdh-skills-private-data`.

**Override:** Set `RHDH_RICH_FILTER_PATH=/path/to/file.json` to use a specific file.

Expand Down
2 changes: 1 addition & 1 deletion skills/release/rhdh-release-status/scripts/rich_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _configured_repo() -> Path | None:
if env_path and Path(env_path).is_dir():
return Path(env_path).resolve()

config_paths = [Path.home() / ".config" / "rhdh-skill" / "config.json"]
config_paths = [Path.home() / ".config" / "rhdh-skills" / "config.json"]
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
Expand Down
2 changes: 1 addition & 1 deletion skills/release/rhdh-release-teams/scripts/rich_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _configured_repo() -> Path | None:
if env_path and Path(env_path).is_dir():
return Path(env_path).resolve()

config_paths = [Path.home() / ".config" / "rhdh-skill" / "config.json"]
config_paths = [Path.home() / ".config" / "rhdh-skills" / "config.json"]
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
Expand Down
Loading
Loading