.claude/skills/setup/SKILL.md
Initialize a new project with the AI Coding Toolkit. Use when setting up toolkit skills in a new or existing project.
npx skillsauth add benjaminshoemaker/ai_coding_project_base setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Initialize a new project at $1 with the AI Coding Toolkit.
.toolkit-marker exists in the current working directorycd into the ai_coding_project_base toolkit repo and re-run /setup $10.5. Idempotency Check
Check if target already has toolkit installed:
if [[ -f "$1/.claude/toolkit-version.json" ]]; then
EXISTING_COMMIT=$(jq -r '.toolkit_commit' "$1/.claude/toolkit-version.json")
CURRENT_COMMIT=$(git rev-parse HEAD)
fi
Decision logic:
toolkit-version.json doesn't exist → proceed with full setup (existing flow)toolkit_commit = current HEAD → report "Already up to date" and skip to Step 7 (success report)toolkit_commit ≠ current HEAD → proceed with incremental update (Step 3a)Store the result as SETUP_MODE:
SETUP_MODE=full — new installationSETUP_MODE=current — already up to dateSETUP_MODE=incremental — updating existing installationValidate target directory
$1 is empty, ask the user for the target directory pathAsk project type
2a. For Feature type: Ask feature name and create directory
- Prompt: "What should this feature be called? (used as folder name, e.g., 'analytics-dashboard')"
- Validate: lowercase, hyphens and underscores allowed, no spaces or special characters
- Create $1/features/ directory if it doesn't exist
- Create $1/features/<feature-name>/ directory
- Store the feature path as FEATURE_PATH = $1/features/<feature-name>
Copy skills to target (with global resolution check)
Before copying each skill, check if it's globally available. See GLOBAL_SYNC.md for helper definitions.
Pre-copy checks:
# Source the global sync helpers
GLOBAL_SKILLS_DIR="$HOME/.claude/skills"
TOOLKIT_ROOT="$(pwd)"
# Check if global directory exists and has symlinks
GLOBAL_AVAILABLE=false
if [[ -d "$GLOBAL_SKILLS_DIR" ]]; then
# Count symlinks pointing to this toolkit
SYMLINK_COUNT=$(find "$GLOBAL_SKILLS_DIR" -maxdepth 1 -type l 2>/dev/null | wc -l)
if [[ "$SYMLINK_COUNT" -gt 0 ]]; then
GLOBAL_AVAILABLE=true
fi
fi
Copy logic with global resolution:
GLOBAL_COUNT=0
LOCAL_COUNT=0
for skill_dir in .claude/skills/*/; do
skill_name="$(basename "$skill_dir")"
# Check for toolkit-only flag in YAML frontmatter (between --- markers)
if sed -n '/^---$/,/^---$/p' "$skill_dir/SKILL.md" 2>/dev/null | grep -q '^toolkit-only: true'; then
continue # Skip toolkit-only skills
fi
# Check if this skill is globally usable
if [[ "$GLOBAL_AVAILABLE" == "true" ]]; then
global_path="$GLOBAL_SKILLS_DIR/$skill_name"
if [[ -L "$global_path" && -e "$global_path" ]]; then
# Verify it points to this toolkit
resolved=$(realpath "$global_path" 2>/dev/null)
expected=$(realpath "$skill_dir" 2>/dev/null)
if [[ "$resolved" == "$expected" ]]; then
echo " $skill_name — globally available"
((GLOBAL_COUNT++))
continue # Skip copy, will resolve via global
fi
fi
fi
# Copy locally
cp -r "$skill_dir" "$1/.claude/skills/"
echo " $skill_name — copied locally"
((LOCAL_COUNT++))
done
Summary output:
"All skills resolved via ~/.claude/skills/ — no local copies needed""Skills: {GLOBAL_COUNT} global, {LOCAL_COUNT} local""Copied {LOCAL_COUNT} skills to project"Copy verification config (if missing):
.claude/verification-config.json → target's .claude/verification-config.jsonVerify result:
# For local-only or mixed: verify local copies exist
if [[ "$LOCAL_COUNT" -gt 0 ]]; then
actual_count=$(ls -d "$1/.claude/skills/"*/ 2>/dev/null | wc -l)
if [[ "$actual_count" -eq 0 ]]; then
# STOP and report copy failure
fi
fi
Also verify configuration file:
test -f "$1/.claude/verification-config.json" && echo "Config: OK" || echo "Config: MISSING (non-critical)"
Verify skill copy results: After the copy loop completes, run ls "$1/.claude/skills/" and confirm the expected skill directories are present. If any expected local copies are missing, STOP and report the failure before continuing.
3b. Copy workstream scripts to target
Copy .workstream/ scripts from the toolkit to the target project:
mkdir -p "$1/.workstream"
for file in lib.sh setup.sh dev.sh verify.sh README.md workstream.json.example; do
if [ -f ".workstream/$file" ]; then
cp ".workstream/$file" "$1/.workstream/$file"
fi
done
chmod +x "$1/.workstream/"*.sh 2>/dev/null || true
Do NOT copy workstream.json — this is project-owned and created by the user.
Verify copies:
ls -la "$1/.workstream/" 2>/dev/null
Confirm setup.sh, dev.sh, verify.sh, and lib.sh exist and are executable.
Verify with ls -la that permissions include +x on all .sh files. If any script is missing or not executable, report the discrepancy.
3c. Copy Codex App templates to target
Copy .codex/ templates from the toolkit to the target project:
mkdir -p "$1/.codex"
cp ".codex/setup.sh" "$1/.codex/setup.sh"
cp ".codex/AGENTS.md" "$1/.codex/AGENTS.md"
chmod +x "$1/.codex/setup.sh"
These are recommended defaults for Codex App integration. Users configure the setup script in Codex App Settings (Cmd+,) → Local Environments.
Verify Codex App copies:
ls -la "$1/.codex/setup.sh" that the file exists and is executable.ls "$1/.codex/AGENTS.md" that the file was copied.3a. Incremental Sync (When SETUP_MODE=incremental)
Skip Step 3 entirely and use this incremental approach instead.
Check resolution mode from existing config:
FORCE_LOCAL=$(jq -r '.force_local_skills // empty' "$1/.claude/toolkit-version.json")
CURRENT_RESOLUTION=$(jq -r '.skill_resolution // "local"' "$1/.claude/toolkit-version.json")
Important: For existing projects with local copies, continue syncing locally to preserve shadowing behavior. Do NOT automatically switch to global resolution.
Load the stored file hashes from $1/.claude/toolkit-version.json:
STORED_HASHES=$(jq '.files' "$1/.claude/toolkit-version.json")
Hash calculation pattern (used for all file comparisons in this step and below):
# Compute SHA-256 hash of a file — used for toolkit, target, and stored hash comparisons
file_hash() { shasum -a 256 "$1" | cut -d' ' -f1; }
For each skill in the copy list (excluding toolkit-only skills — check SKILL.md frontmatter for toolkit-only: true):
TOOLKIT_HASH=$(file_hash "$TOOLKIT_FILE")TARGET_HASH=$(file_hash "$TARGET_FILE")Classification and Action:
| Condition | Classification | Action |
|-----------|----------------|--------|
| Already using global resolution | GLOBAL_USABLE | Skip (resolves via global) |
| Target doesn't exist | NEW | Copy from toolkit |
| Target hash = Toolkit hash | CURRENT | Skip (already up to date) |
| Target hash = Stored hash | CLEAN_UPDATE | Copy from toolkit (no local changes) |
| Target hash ≠ Stored hash | LOCAL_MODIFIED | Skip with warning |
Track counts for each classification and report summary:
INCREMENTAL SYNC
================
Global resolution: {count} skills (via ~/.claude/skills)
New files: {count} copied
Updated files: {count} copied
Current files: {count} skipped (already up to date)
Modified files: {count} skipped (local changes preserved)
If any files are LOCAL_MODIFIED, list them:
WARNING: These files have local modifications and were NOT updated:
- .claude/skills/phase-start/SKILL.md
- .claude/skills/fresh-start/SKILL.md
To update these files, either:
- Run /sync for interactive conflict resolution
- Manually backup and delete them, then re-run /setup
Create or Update toolkit-version.json
For full setup (SETUP_MODE=full):
Create .claude/toolkit-version.json in the target to enable future syncs.
Determine the resolution mode based on how skills were installed:
{
"schema_version": "1.1",
"toolkit_location": "{absolute path to this toolkit}",
"toolkit_commit": "{current git HEAD commit hash}",
"toolkit_commit_date": "{commit date in ISO format}",
"last_sync": "{current ISO timestamp}",
"force_local_skills": null,
"skill_resolution": "{global|local|mixed}",
"files": {
".claude/skills/fresh-start/SKILL.md": {
"hash": "{sha256 hash of file}",
"synced_at": "{ISO timestamp}",
"resolution": "{global|local}"
}
// ... entry for each skill
}
}
Resolution determination:
GLOBAL_COUNT > 0 and LOCAL_COUNT == 0: "skill_resolution": "global"GLOBAL_COUNT == 0 and LOCAL_COUNT > 0: "skill_resolution": "local""skill_resolution": "mixed"Per-file resolution:
"resolution": "global""resolution": "local"For incremental update (SETUP_MODE=incremental):
Update the existing toolkit-version.json:
toolkit_commit to current HEADtoolkit_commit_date to current commit datelast_sync to current timestampforce_local_skills settinghash, synced_at, and resolutionskill_resolution based on all filesFor already current (SETUP_MODE=current):
Skip this step entirely.
Get toolkit info:
TOOLKIT_PATH=$(pwd)
COMMIT_HASH=$(git rev-parse HEAD)
COMMIT_DATE=$(git log -1 --format=%cI HEAD)
Calculate file hashes using the file_hash() pattern defined in Step 3a.
Include entries for ALL files in non-toolkit-only skill directories:
# Hash every .md file in every skill directory (skip toolkit-only)
for skill_dir in .claude/skills/*/; do
# Skip toolkit-only skills (parse YAML frontmatter between --- markers)
if sed -n '/^---$/,/^---$/p' "$skill_dir/SKILL.md" 2>/dev/null | grep -q '^toolkit-only: true'; then
continue
fi
for file in "$skill_dir"*.md; do
[[ -f "$file" ]] || continue
hash=$(file_hash "$file")
# Add entry for "$file" with hash and timestamp
done
done
This ensures skills with supporting files (e.g., audit-skills/CRITERIA.md,
audit-skills/SCORING.md) are tracked for conflict detection.
Skills with toolkit-only: true in frontmatter are NOT copied or tracked.
These run only from the toolkit directory (e.g., setup, update-target-projects).
Verify toolkit-version.json: Read back the file with cat "$1/.claude/toolkit-version.json" | python3 -m json.tool (or jq .) to confirm it contains valid JSON and the toolkit_commit field matches the expected value.
Create CLAUDE.md if it doesn't exist
Create a minimal CLAUDE.md that references AGENTS.md:
@AGENTS.md
Verify CLAUDE.md: Read back $1/CLAUDE.md to confirm it was written correctly and contains the @AGENTS.md reference.
Codex CLI Detection (Optional)
Check if OpenAI Codex CLI is installed:
command -v codex >/dev/null 2>&1
If Codex is detected:
Question: "Codex CLI detected. Install toolkit skills for Codex?"
Options:
- "Yes, install" — Install skills via symlink (auto-updates with toolkit)
- "No, skip" — Don't install Codex skills
If user selects "Yes, install":
./scripts/install-codex-skill-pack.sh --method symlink
ls -la ~/.codex/skills/ that symlinks were created successfully.If Codex is not detected:
Note: Using symlinks means Codex skills auto-update when user runs git pull on the toolkit.
6a. Codex MCP Configuration (if Codex detected and skills installed)
After installing Codex skills, offer to configure essential MCPs:
Question: "Configure essential MCP servers for Codex? (Playwright for browser verification)"
Options:
- "Yes, configure" — Add Playwright MCP to ~/.codex/config.toml
- "No, skip" — Skip MCP configuration
If user selects "Yes, configure":
./scripts/configure-codex-mcp.sh
cat ~/.codex/config.toml that the MCP configuration was written correctly.Why this matters: Both Claude Code and Codex CLI support the same MCP protocol. This ensures Codex has access to browser automation for verification workflows, matching Claude Code's capabilities when using the Playwright MCP.
Report success and next steps
For SETUP_MODE=current (already up to date):
ALREADY UP TO DATE
==================
Target: $1
Toolkit commit: {COMMIT_HASH} ({COMMIT_DATE})
No changes needed — toolkit files are current.
For SETUP_MODE=incremental (updated existing):
TOOLKIT UPDATED
===============
Target: $1
Previous commit: {OLD_COMMIT_HASH}
Current commit: {COMMIT_HASH}
{Summary from Step 3a showing files synced/skipped}
All toolkit skills are now up to date.
For SETUP_MODE=full, Greenfield:
TOOLKIT INITIALIZED
===================
Target: $1
Skill resolution: {mode} ({details})
Next steps (run from your project directory):
1. cd $1
2. /product-spec
3. /technical-spec
4. /generate-plan
5. cd plans/greenfield
6. /fresh-start
7. /configure-verification
8. /phase-prep 1
9. /phase-start 1
Skill resolution line examples:
Skill resolution: global (30 skills via ~/.claude/skills symlinks)Skill resolution: local (30 skills copied to project)Skill resolution: mixed (25 global, 5 local)For SETUP_MODE=full, Feature:
TOOLKIT INITIALIZED
===================
Target: $1
Feature directory: FEATURE_PATH
Next steps (run from your project directory):
1. cd $1
2. /feature-spec <feature-name>
3. /feature-technical-spec <feature-name>
4. /feature-plan <feature-name>
5. cd features/<feature-name>
6. /fresh-start
7. /configure-verification
8. /phase-prep 1
9. /phase-start 1
/product-spec, /technical-spec, /generate-plan, /feature-spec, /feature-technical-spec, /feature-plan, and execution skills) run from the target project directory/setup and /update-target-projects run from the toolkitcp -r for directory copies to preserve structure| Situation | Action |
|-----------|--------|
| Target directory does not exist and mkdir -p fails | Report permission error, suggest creating manually, exit without partial state |
| cp -r fails when copying skills to target | STOP immediately, report which skills failed to copy, do not write toolkit-version.json |
| toolkit-version.json write fails or produces invalid JSON | Complete file copies (primary goal), warn that incremental syncs will not work, suggest checking .claude/ directory permissions |
| Codex CLI skill installation fails | Do NOT fail the entire setup; report the error and continue with remaining steps |
| Global symlink check fails (broken symlinks in ~/.claude/skills/) | Fall back to local copy for affected skills, report which symlinks are broken |
If LOCAL_MODIFIED files conflict during incremental sync:
.claude/backup/ before overwritingIf target directory doesn't exist and can't be created:
mkdir -p {path}If Codex CLI skill installation fails:
./scripts/install-codex-skill-pack.sh manually."If toolkit-version.json cannot be written:
testing
Audit project alignment with VISION.md, identify SDLC gaps, and generate feature proposals. Use when reviewing strategic direction or planning new features.
development
Run code-verification on a specific task. Use to verify a single task's acceptance criteria after implementation.
testing
Resolve Vercel preview deployment URL for the current git branch. Invoked by browser-verification when deployment.enabled is true, or directly to check deployment status. Use to check deployment status or when browser verification needs a URL.
tools
Discover and sync all toolkit-using projects with the latest skills. Use when skills are modified, after the post-commit hook reminds you, or to batch-sync multiple projects.