diegomarino/claude-toolshed/dev-setup

Claude Code and agent skill by diegomarino/claude-toolshed

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Generate dev server lifecycle scripts (start/stop/status/ports) from detected project structure

Install

npx vskill@latest install diegomarino/claude-toolshed/dev-setup

SKILL.md

/dev-setup

User request: "$ARGUMENTS"

Task

Detect the project's structure, propose a dev environment configuration, and generate bash scripts for managing servers, Chrome profiles, and worktree port isolation.

Process

Step 0: Ensure dependencies

Resolve plugin path:

bash
SKILL_DIR="$(find "$HOME/.claude/plugins/cache" -type d -name "dev-setup" -path "*/skills/dev-setup" 2>/dev/null | head -1)"
[[ -z "$SKILL_DIR" ]] && SKILL_DIR="$(find "$HOME" -maxdepth 8 -type d -name "dev-setup" -path "*/skills/dev-setup" 2>/dev/null | head -1)"
bash
bash "$SKILL_DIR/scripts/ensure-deps.sh"

If the script exits with an error, show the missing dependency message to the user and stop. Warnings about optional tools can be shown but should not block execution.

Route: upgrade

If $ARGUMENTS starts with "upgrade":

Read references/upgrade-route.md and follow the steps there.


Route: health

If $ARGUMENTS starts with "health":

  1. Resolve plugin path (same as upgrade route)
  2. Run the health check script:

``bash bash "$SKILL_DIR/reference/dev-setup-health.sh" ``

  1. Print the output to the user. Then stop — do not continue to Step 1.

Step 1: Resolve project root

If $ARGUMENTS is a non-empty path, use it as the project root. Otherwise use the current directory ($PWD).

bash
PROJECT_ROOT="${ARGUMENTS:-$PWD}"
cd "$PROJECT_ROOT"
Important: Claude's Bash tool does not preserve cd between calls. Prefix every subsequent Bash command in Steps 2-5 with cd "$PROJECT_ROOT" && to ensure all detection runs in the correct directory.
Step 2: Detect package manager

Run the following detection in Bash:

bash
if [[ -f pnpm-lock.yaml ]]; then PM=pnpm
elif [[ -f bun.lock ]] || [[ -f bun.lockb ]]; then PM=bun
elif [[ -f yarn.lock ]]; then PM=yarn
elif [[ -f package-lock.json ]]; then PM=npm
elif [[ -f Cargo.toml ]]; then PM=cargo
elif [[ -f go.mod ]]; then PM=go
else PM=none
fi
echo "PM=$PM"
Step 3: Detect services and ports

First check if package.json exists:

bash
[[ -f package.json ]] && echo "NODE=true" || echo "NODE=false"

If NODE=false, skip the python3 snippet and the concurrently check in Step 4 — set CONCURRENTLY=false and note "not a Node project".

Scope note: Service detection, runner options, and package.json script generation (Steps 3-9) assume a Node/JS project. For non-Node stacks (cargo, go, etc.), only dev-post-checkout.sh (dependency install) is generated reliably. Tell the user: "Service management scripts for [stack] are not yet supported — only dependency install was generated. You can add custom start/stop scripts to <SCRIPT_DIR>/ manually."

Read package.json scripts for entries matching dev:*, start, serve, preview:

bash
python3 -c "
import json, sys
d = json.load(open('package.json'))
for k, v in d.get('scripts', {}).items():
if any(x in k for x in ['dev', 'start', 'serve', 'preview', 'storybook']):
print(f'SCRIPT={k} CMD={v}')
" 2>/dev/null || true

Read existing port assignments from env files:

bash
grep -hE "^([A-Z][A-Z0-9_]*_WT_PORT|VITE_[A-Z_]*)=" \
.env.example .env 2>/dev/null | head -20 \
|| echo "ENV_FILES=none"

Try Context7 first. If resolve-library-id returns no match or query-docs returns no relevant result, use the WebFetch fallback URL instead.

If vite.config.* exists, resolve current Vite port API:

  • Use Context7: resolve-library-id "vite" → query-docs "dev server port configuration"
  • Fallback (WebFetch): https://vitejs.dev/config/server-options.html

If docker-compose.yml exists:

  • Use Context7: resolve-library-id "docker compose" → query-docs "ports mapping"
  • Fallback (parse directly — no docs needed): grep -A2 'ports:' docker-compose.yml
Step 4: Detect existing scripts and runtime tools
bash
# Find existing bash scripts
find . -maxdepth 4 \( -name "*.sh" -o -name "devctl" \) \
-not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null
# Detect script directory convention (first match wins)
SCRIPT_DIR=""
for d in tools/dev scripts bin devtools; do
[[ -d "$d" ]] && SCRIPT_DIR="$d" && echo "SCRIPT_DIR=$d" && break
done
[[ -z "$SCRIPT_DIR" ]] && echo "SCRIPT_DIR=tools/dev (will create)"
# Runtime tools
for t in tmux shellcheck shfmt ttyd; do
command -v "$t" >/dev/null 2>&1 \
&& echo "TOOL=$t STATUS=available" \
|| echo "TOOL=$t STATUS=missing"
done
# concurrently in deps
grep -q '"concurrently"' package.json 2>/dev/null \
&& echo "CONCURRENTLY=true" || echo "CONCURRENTLY=false"

If shellcheck is missing (STATUS=missing), warn the user: "Required tool shellcheck not found. Run /dev-setup health for install instructions."

Step 5: Detect Chrome and gtr config
bash
# Chrome
grep -hE "^(CHROME_PROFILE|CHROME_CDP_WT_PORT)=" .env.example .env 2>/dev/null \
|| echo "CHROME=not-configured"
# git gtr
command -v gtr >/dev/null 2>&1 && echo "GTR_BINARY=found" || echo "GTR_BINARY=missing"
[[ -f .gtrconfig ]] && echo "GTRCONFIG=found" && cat .gtrconfig || echo "GTRCONFIG=none"
[[ -f .gtr-setup.sh ]] && echo "GTR_SETUP=found" || echo "GTR_SETUP=none"

Set GTR="yes" if GTR_BINARY=found, GTR="no" otherwise. Do not ask the user — presence in PATH is the decision.

If .gtrconfig exists, use Context7 to validate hook syntax:

Try Context7 first. If resolve-library-id returns no match or query-docs returns no relevant result, use the WebFetch fallback URL instead.

  • resolve-library-id "git-worktree-runner" → query-docs "postCreate hook env vars WORKTREE_PATH BRANCH"
  • Fallback: WebFetch https://github.com/coderabbitai/git-worktree-runner
Step 6: Propose configuration — Call A

Summarize the detected project in 2-3 lines (package manager, services found, tools available), then call AskUserQuestion with these 4 questions:

Constraint: Each call supports 1-4 questions with 2-4 options each.

AskUserQuestion (4 questions):
Q1 — header: "Services", multiSelect: true
question: "Which services should be managed? (detected from project)"
options — build dynamically from detected SCRIPT entries (up to 4), e.g.:
- label: "api :3000" description: "Backend server (PORT=3000)"
- label: "web :5173" description: "Frontend dev server (WEB_WT_PORT=5173)"
- label: "storybook :61000" description: "Component explorer (STORYBOOK_WT_PORT=61000)"
- label: "ttyd :7681" description: "Browser terminal (TTYD_WT_PORT=7681)"
Note: show only detected services. If fewer than 2 detected, add a generic "custom :3000" option alongside any detected ones (do not replace them).
Q2 — header: "Runner", multiSelect: false
question: "How should servers be launched?"
options:
- label: "tmux" description: "Detached 3-pane session per branch. Requires tmux." (append " (not found on PATH)" if tmux STATUS=missing)
- label: "concurrently" description: "All servers in one terminal. No tmux required."
- label: "tmux + fallback" description: "tmux when available, concurrently otherwise."
- label: "manual only" description: "Generate scripts but no auto-launcher."
Q3 — header: "Chrome", multiSelect: false
question: "Set up an isolated Chrome dev profile?"
options:
- label: "Yes — create profile" description: "Creates ~/.chrome-profiles/<name> and a launcher."
- label: "No — skip" description: "Skip. Re-run /dev-setup to add later."
Q4 — header: "Script dir", multiSelect: false
question: "Where should scripts be placed?"
options — if a dir was detected in Step 4 (SCRIPT_DIR was set without "(will create)"), move that matching option to the first position; otherwise use this order:
- label: "tools/dev/" description: "Recommended. Mirrors reference pattern."
- label: "scripts/" description: "Common alternative."
- label: "bin/" description: "Minimal convention."
- label: "devtools/" description: "Custom directory (will be created)."

Store the user's answers as:

  • SELECTED_SERVICES — array of selected labels
  • RUNNER — selected label
  • CHROME — selected label
  • SCRIPT_DIR — selected label (strip trailing slash for filesystem use)
Step 7: Propose configuration — Call B (conditional)

Only run Call B if `CHROME = "Yes — create profile".`

If not, skip to Step 8.

AskUserQuestion (1 question):
Q1 — header: "Profile name", multiSelect: false
question: "Chrome profile name and CDP port?"
options — derive <project-name> from package.json "name" field or directory basename:
- label: "<project-name> :19222" description: "Profile: chrome-<project-name>, CDP: 19222"
- label: "<project-name> :19223" description: "Profile: chrome-<project-name>, CDP: 19223"
- label: "<project-name> :19224" description: "Profile: chrome-<project-name>, CDP: 19224"
- label: "Other" description: "Enter name and port manually — skill will prompt"

Store answers as:

  • CHROME_PROFILE_NAME — profile name extracted from label (e.g. "myapp" from "myapp :19222"), or if "Other": ask user for profile name (string, no spaces) and CDP port (number) separately
  • CHROME_CDP_WT_PORT — port extracted from label (e.g. "19222")

Script Conventions

Apply these patterns to ALL generated scripts.

Strict mode

All standalone scripts: set -euo pipefail Sourced utilities (dev-read-ports.sh, dev-session-name.sh): NO strict mode — it would bleed into the caller shell.

Port reading (dev-read-ports.sh) and session naming (dev-session-name.sh)

Both are sourced utilities — no `set -euo pipefail` (would bleed into caller). See reference files for full pattern. Key behaviors:

  • _read_env VAR DEFAULT reads from .wt-ports.env → .env → .env.example (first match wins)
  • dev_session_name returns b-<branch> (normalized lowercase, hyphens)
  • Adapt exported port vars to match SELECTED_SERVICES (don't hardcode all 4 from reference)
Output format — ALL status/lifecycle scripts

Emit KEY=value lines, no ANSI color, one line per entity:

SERVICE=api PORT=3000 STATUS=running PID=12345 PROCESS=node
TMUX=b-main STATUS=active ATTACHED=false
CHROME=chrome-myapp STATUS=running CDP_PORT=19222 CDP_URL=http://localhost:19222
Port variable naming

All vars ending in _WT_PORT are worktree-isolated service ports written to .wt-ports.env per worktree. Config/range vars use PORT_ prefix (e.g. PORT_MIN, PORT_MAX).

ServiceEnv var
API serverAPI_WT_PORT
Web/ViteWEB_WT_PORT
StorybookSTORYBOOK_WT_PORT
ttydTTYD_WT_PORT
Chrome CDPCHROME_CDP_WT_PORT
Port allocator (dev-allocate-ports.sh)

Standalone script that allocates N consecutive free ports from a safe pool (20000-29999). Uses lsof -nP -iTCP:"$port" -sTCP:LISTEN to verify availability. Two modes:

  • Allocate: bash dev-allocate-ports.sh 4 → prints 4 consecutive free ports
  • Validate: bash dev-allocate-ports.sh 4 --validate 23847 23848 23849 23850 → checks ports, suggests replacements if occupied

See $SKILL_DIR/reference/dev-allocate-ports.sh for the full pattern.

Worktree port allocator (dev-wt-ports.sh)

Calls dev-allocate-ports.sh to get a block of free ports, then writes them to .wt-ports.env. Must use $WORKTREE_PATH and $BRANCH env vars (set by git gtr postCreate hook), not $PWD.

Step 8: Generate bash scripts

Using the user's answers (SELECTED_SERVICES, RUNNER, CHROME, SCRIPT_DIR, GTR) and the convention patterns above, generate each script. Throughout this section, <SCRIPT_DIR> refers to the $SCRIPT_DIR value collected in Step 6 — replace it with the actual path (e.g. tools/dev) everywhere it appears. For every file:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
44
Repository forks
4
7-day trend score
19

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 18 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/diegomarino/claude-toolshed/dev-setup/badge)](https://verified-skill.com/skills/diegomarino/claude-toolshed/dev-setup)

Something wrong with this skill or its page? Tell us.