Claude Code skills for retrofitting OpenShift quickstarts with Navigator-compatible installers and machine-readable manifests.
These skills guide engineers through the process of adding a standardized deployment interface to any quickstart — regardless of whether it uses Helm, Makefiles, ArgoCD, or shell scripts — so that the Navigator can orchestrate it.
Generates a containerized installer that wraps your quickstart's existing deployment mechanism in a Kubernetes Job. The installer provides a uniform interface for the Navigator to run actions like install, uninstall, and status checks.
What it generates:
| File | Purpose |
|---|---|
installer/entrypoint.sh |
Main orchestrator — action routing, structured JSON output, termination messages |
installer/deploy.sh |
Navigator proxy — creates RBAC, runs the Job, monitors it, retrieves results |
installer/build.sh |
Builds and pushes the installer container image |
installer/Dockerfile |
UBI9-based container with deployment tools (oc, helm, etc.) |
installer/lib/*.sh |
Action implementations (install, uninstall, status, prerequisites, upgrade) |
How it works:
- Explores your repo to understand the existing deployment approach
- Asks you to confirm findings and fill in gaps
- Reads templatized reference files and adapts them to your quickstart
- Generates all installer files, wiring your existing scripts/charts/manifests into the standard action framework
Generates a quickstart-manifest.yaml — the machine-readable metadata file that tells the Navigator everything it needs to know about your quickstart: what it is, what it needs, how to deploy it, and what RBAC to create.
How it works:
- Auto-discovers information from your repo — Helm values (CPU, memory, GPU, storage), Chart.yaml dependencies, operator subscriptions, routes, health endpoints, README content
- Interviews you section-by-section, presenting discovered values as defaults you can accept or override
- Generates the RBAC section by analyzing what Kubernetes resources your quickstart creates
- Writes and validates the manifest against the JSON Schema
- Claude Code CLI or IDE extension installed
- Access to an OpenShift cluster for testing generated installers
Step 1: Register the marketplace source
Add the marketplace entry to your ~/.claude/settings.json. If the file already has content, merge the extraKnownMarketplaces and enabledPlugins entries into the existing JSON:
{
"extraKnownMarketplaces": {
"quickstart-navigator": {
"source": {
"source": "github",
"repo": "rh-ai-quickstart/quickstart-navigator-integration"
}
}
},
"enabledPlugins": {
"navigator@quickstart-navigator": true
}
}Step 2: Restart Claude Code
Close and reopen Claude Code (or start a new session). On startup, it will clone the marketplace repo, cache the plugin, and load the skills.
Step 3: Verify
The skills should appear in your available skills list. You can invoke them with:
/navigator:retrofit-quickstart-installer/navigator:generate-quickstart-manifest
If the skills don't appear after restart:
- Check marketplace was cloned: Look for files under
~/.claude/plugins/marketplaces/quickstart-navigator/ - Check plugin was cached: Look for files under
~/.claude/plugins/cache/quickstart-navigator/navigator/ - Check install record: Read
~/.claude/plugins/installed_plugins.json— it should have anavigator@quickstart-navigatorentry - If cache is empty but marketplace exists: Copy the plugin manually:
Then restart Claude Code again.
VERSION=$(jq -r '.plugins["navigator@quickstart-navigator"][0].version' ~/.claude/plugins/installed_plugins.json) mkdir -p ~/.claude/plugins/cache/quickstart-navigator/navigator/$VERSION cp -R ~/.claude/plugins/marketplaces/quickstart-navigator/navigator/ \ ~/.claude/plugins/cache/quickstart-navigator/navigator/$VERSION/
The plugin updates automatically when Claude Code starts a new session. To force an update, delete the cache and restart:
rm -rf ~/.claude/plugins/cache/quickstart-navigatorOpen your quickstart project in Claude Code and run:
/navigator:retrofit-quickstart-installer
The skill will explore your repo, ask you about your deployment mechanism, and generate the installer files. After generation:
# Build and push the installer image
./installer/build.sh push
# Test prerequisites checking
./installer/deploy.sh check_pre_reqs <namespace>
# Test status reporting
./installer/deploy.sh status <namespace>
# Run a full install
./installer/deploy.sh install <namespace>Open your quickstart project in Claude Code and run:
/navigator:generate-quickstart-manifest
The skill will scan your Helm charts and scripts, then walk you through each manifest section. After generation, verify in VS Code — the schema reference enables autocomplete and validation.
The full end-to-end flow for Navigator-enabling a quickstart:
- Generate manifest —
/navigator:generate-quickstart-manifestscans your repo and interviews you to producequickstart-manifest.yaml - Generate installer —
/navigator:retrofit-quickstart-installercreates the containerized installer that wraps your deployment mechanism - Build the image —
./installer/build.sh pushbuilds and pushes the installer container - Test on a live cluster — Run all four actions and verify each one:
./installer/deploy.sh check_pre_reqs <namespace> ./installer/deploy.sh install <namespace> ./installer/deploy.sh status <namespace> ./installer/deploy.sh uninstall_delete_all <namespace>
- Fix and iterate — Rebuild (
./installer/build.sh push) and retest after each fix
Test on the same OpenShift and RHOAI version you plan to support — API behavior and CRD availability vary across versions.
These patterns have caused issues in real quickstart deployments:
- Job name exceeds 63 characters — Kubernetes labels are capped at 63 chars. Long quickstart names combined with action names like
uninstall-delete-alland a full Unix timestamp can exceed this. The deploy template uses{{SHORT_NAME}}(max ~20 chars) to keep names short. - grep exits with code 1 under pipefail —
grepreturns exit code 1 when no lines match. Underset -euo pipefail, this kills the script. Wrap with{ grep PATTERN || true; }. - CPU reported in millicores — Node allocatable CPU may be
8000minstead of8. Always handle both formats in jq. - Operator detection needs extra RBAC —
oc get csv -A | greprequiresoperators.coreos.compermissions. Detect operators via CRD existence instead (oc get crd <crd-name>). - GPU pods fail to schedule — Cluster admins use custom taint keys on GPU nodes (not just
nvidia.com/gpu). Auto-detect taint keys and let users override. - Helm --wait needs replicasets permission — Always include
replicasetsin theappsAPI group alongsidedeploymentsandstatefulsets. - Shell compatibility — Avoid bash4-only syntax like
${VAR,,}. Use== "y" || == "Y"comparisons for portability across bash/zsh.
The installer runs as a Kubernetes Job in the default namespace. The Navigator (or deploy.sh for manual testing) creates RBAC, launches the Job, monitors it, and cleans up.
Navigator / deploy.sh
│
├─ Creates RBAC (ServiceAccount, Role, ClusterRole, bindings)
├─ Creates Job in default namespace
├─ Monitors logs and polls for completion
├─ Retrieves termination message
└─ Cleans up RBAC
│
▼
Installer Job (runs in default namespace)
│
├─ Validates action and mode
├─ Executes action (install, uninstall, status, etc.)
├─ Writes termination message to /dev/termination-log
├─ Annotates Job with termination message (durable)
└─ Creates log ConfigMap in default namespace (7-day TTL)
- deploy.sh creates: ServiceAccount + Role + RoleBinding in
default, ClusterRole + ClusterRoleBinding - Installer uses: ClusterRole permissions (namespace-scoped rules apply to ALL namespaces via ClusterRoleBinding)
- deploy.sh cleans up: All of the above after Job completes
The installer never manages its own RBAC. The ClusterRole grants permissions across all namespaces, so the installer can create the target namespace and deploy resources into it without separate per-namespace Role/RoleBinding.
Installer results are stored in three places with decreasing ephemerality:
| Location | Lifespan | How to retrieve |
|---|---|---|
| Pod termination message | Until pod is garbage collected | oc get pods -l job-name=<JOB> -o jsonpath='{.items[0].status.containerStatuses[0].state.terminated.message}' |
| Job annotation | Until Job is deleted | oc get job <JOB> -n default -o jsonpath='{.metadata.annotations.<name>-installer/termination-message}' |
| Log ConfigMap | 7 days (TTL label) | oc get configmap <name>-installer-log-<JOB> -n default -o jsonpath='{.data.log}' |
The quickstart-manifest.yaml conforms to quickstart.redhat.com/v1. The JSON Schema is included in this repo at navigator/skills/generate-quickstart-manifest/references/quickstart-manifest.schema.json and is copied into each quickstart project for IDE validation.
Top-level sections:
| Section | Purpose |
|---|---|
metadata |
Identity, version, description, maintainer |
versioning |
Upgrade paths and installer image tag |
classification |
Industries, use cases, technologies, tags (catalog search) |
prerequisites |
OpenShift version, operators, resources, storage, external services |
deployment |
Supported actions/modes, installer image, RBAC requirements, deployed resources |
parameters |
User-configurable secrets and settings |
status |
Health endpoint and polling configuration |
access |
Application endpoints and default credentials |
cleanup |
Data description and uninstall warnings |
documentation |
Links to guides and docs |
llmContext |
When to recommend, FAQ (for Navigator chat) |
The peoplemesh quickstart is the reference implementation. Its installer/ directory and quickstart-manifest.yaml were built using the patterns codified in these skills.
To update the skills or templates:
- Clone this repo
- Edit files under
navigator/skills/ - Commit and push — engineers will get updates on next plugin install/update