From rdl-team
Onboard a user onto the RDL team's Claude Code setup. Use when the user wants to "set up Claude Code", "set up my .claude", "onboard onto the RDL Claude Code setup", "install the forced-eval hook", or "configure Claude Code for the team". Asks whether to configure a project-local `.claude/` or the user's global `~/.claude/`, then installs the team's `forced-eval-hook.sh` (a UserPromptSubmit hook that surfaces available skills as advisory context) and wires it into the chosen scope's `settings.json` idempotently. The minimal first step of RDL Claude Code onboarding — later passes will guide the wider settings surface.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rdl-team:cc-setup Set up Claude Code for the RDL team? (say 'project' for this repo's .claude/, or 'global' for ~/.claude/)Set up Claude Code for the RDL team? (say 'project' for this repo's .claude/, or 'global' for ~/.claude/)The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Your job is to onboard the user onto the RDL team's Claude Code configuration. This
Your job is to onboard the user onto the RDL team's Claude Code configuration. This
first pass does one concrete thing: install the team's forced-eval-hook.sh and
wire it as a UserPromptSubmit hook in the scope the user chooses. The hook script
ships in this skill's assets/ directory; you copy it into the target .claude/ and
merge the settings idempotently.
Scope. The forced-eval hook is the floor, not the ceiling. Do not configure model, permissions, MCP servers, or other settings here unless the user explicitly asks. The one addition beyond the hook is an optional plugin-discovery pass (Phase 4) that reviews the RDL marketplace and the team's extra marketplaces and suggests a plugin set — it only recommends and installs on confirmation. A future pass will turn this into a fuller guided tour of the Claude Code settings surface.
forced-eval-hook.sh is a UserPromptSubmit hook. When a prompt expresses intent to
use a skill (an action verb sits near "skill"/"skills"), it discovers the available
skills and slash commands — standalone (~/.claude/skills/*/SKILL.md) and plugin
(~/.claude/plugins/installed_plugins.json) — and emits them as advisory context
so the model considers them. It is a silent no-op otherwise. The framing is
descriptive; it does not coerce a fixed activation sequence. It uses jq when present
and degrades gracefully without it.
Ask the user where to install (unless they already said in the invocation):
| Scope | Install the script to | Wire the hook in | Use when |
|---|---|---|---|
| project | <repo>/.claude/hooks/forced-eval-hook.sh | <repo>/.claude/settings.json | configuring one repo; the setting can be committed and shared with the team |
| global | ~/.claude/hooks/forced-eval-hook.sh | ~/.claude/settings.json | the user wants the hook on every project they open |
Notes:
.claude/settings.json (committed, team-shared).
If the user wants it personal/uncommitted, use .claude/settings.local.json instead
(same hooks block; gitignored)..git directory before treating it as the project
scope target.Copy assets/forced-eval-hook.sh from this skill into the chosen hooks/ directory,
creating it if absent, and make it executable:
# project scope
mkdir -p .claude/hooks
cp <this skill's assets>/forced-eval-hook.sh .claude/hooks/forced-eval-hook.sh
chmod +x .claude/hooks/forced-eval-hook.sh
# global scope
mkdir -p "$HOME/.claude/hooks"
cp <this skill's assets>/forced-eval-hook.sh "$HOME/.claude/hooks/forced-eval-hook.sh"
chmod +x "$HOME/.claude/hooks/forced-eval-hook.sh"
Resolve <this skill's assets> to this skill's own assets/ directory. On an
installed plugin the skill lives in the plugin cache — locate it rather than guessing:
SRC="$(find "$HOME/.claude/plugins" -path '*/cc-setup/assets/forced-eval-hook.sh' 2>/dev/null | head -1)"
# Fallback: the absolute path of the assets/ directory beside this SKILL.md.
SRC="${SRC:-<absolute path to this skill>/assets/forced-eval-hook.sh}"
If the target file already exists and differs, show the diff and ask before overwriting.
UserPromptSubmit hookMerge this block into the chosen settings.json (command path matches Phase 1's
install location). Show the diff before writing, and merge idempotently — never
clobber existing keys, and dedupe by exact command string so re-running is a no-op.
Shell-form hook commands run via sh -c, so keep the variable double-quoted inside
the JSON string ("$CLAUDE_PROJECT_DIR" / "$HOME") — an unquoted path that contains
spaces would word-split and the hook would fail to launch.
Project scope (.claude/settings.json) — use $CLAUDE_PROJECT_DIR so the path is
portable:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/forced-eval-hook.sh",
"timeout": 10
}
]
}
]
}
}
Global scope (~/.claude/settings.json) — use $HOME:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "\"$HOME\"/.claude/hooks/forced-eval-hook.sh",
"timeout": 10
}
]
}
]
}
}
Merge rules when the file already exists:
hooks.UserPromptSubmit exists, append this rule group
to it only if no group already references forced-eval-hook.sh.hooks or hooks.UserPromptSubmit is absent, create it.jq . <settings file> parses without error.test -x <path> succeeds).printf '{"prompt":"please use a skill"}' | <installed forced-eval-hook.sh>
expect it to emit the skill catalogue (or exit 0 quietly if no skills are installed);
printf '{"prompt":"hello"}' | <script> should exit 0 with no output.Offer — don't force — to review what plugins are available across the RDL marketplace and the team's extra marketplaces and suggest a set for this repo. Run this on first setup and whenever the user re-runs setup (it is idempotent: it drops anything already enabled). If the user declines, skip straight to Phase 5.
Delegate the discovery to the marketplace-scout agent (Task tool). It locates the
team's tracked-marketplace list (marketplaces.json — shipped in this skill's own assets/),
enumerates the live plugin catalog of every tracked
marketplace, inspects this repo's languages/tooling, and returns a ranked suggestion list:
pr-review-toolkit@claude-plugins-official, gh@rdl-agent-extensions,
worktrunk@worktrunk, plus the applicable LSP (gopls-lsp@claude-plugins-official for Go;
the official marketplace ships more *-lsp plugins the scout matches by language).go@rdl-agent-extensions, terraform@rdl-agent-extensions, astral@astral-sh, …).The marketplace list lives in assets/marketplaces.json beside this skill (resolve it the
same way as the hook script in Phase 1: prefer the installed plugin-cache copy, fall back to
the path beside this SKILL.md). The agent reads it; you don't have to.
Present the scout's menu and let the user pick. For each marketplace a chosen plugin needs, register it and install only the confirmed plugins (this skill installs them directly):
# Register each marketplace the chosen plugins need (idempotent), then install.
claude plugin marketplace add <owner>/<repo> # e.g. nq-rdl/agent-extensions for @rdl-agent-extensions
claude plugin install <plugin>@<marketplace> # only the ones the user confirmed
Never install without confirmation. Self-marketplace guard: if the target repo is
itself the rdl-agent-extensions marketplace (a .claude-plugin/marketplace.json with name: rdl-agent-extensions — e.g.
agent-extensions itself), skip every @rdl-agent-extensions plugin. Installing the
published copy of any @rdl-agent-extensions id (including the baseline's gh@rdl-agent-extensions) shadows the working
tree's own copy. This install has no automatic self-exclusion, so you must exclude
@rdl-agent-extensions ids yourself here — the working tree already provides those skills.
Tell the user, concisely:
.claude/hooks/forced-eval-hook.sh and the settings
change so the team picks them up (or note it is personal if they chose
settings.local.json).Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
npx claudepluginhub nq-rdl/agent-extensions --plugin rdl-team