newproject — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited newproject (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The user wants to start a project under their workspace directory $WORKSPACE_DIR (default ~/projects/). The folder may not exist yet OR it may already exist with partial setup (e.g., they did mkdir $WORKSPACE_DIR/foo and code $WORKSPACE_DIR/foo already). Your job: detect what's in place and create only what's missing — never overwrite existing user content.
$WORKSPACE_DIR/<name>/ — empty project directory$WORKSPACE_DIR/<name>/CLAUDE.md — starter project documentation (stub)~/.claude/projects/<project-slug>/memory/ — memory dir (with universal-symlink fan-out if a fanout-memory.sh helper exists in $WORKSPACE_DIR/scripts/)$WORKSPACE_DIR/<name>/.git/ — initialized git repo with sensible .gitignoreorigin set and a bootstrap commit pushed — plus any web-session skills copied into $WORKSPACE_DIR/<name>/.claude/skills/ if your workspace keeps a scripts/web-skills/ source (private repos only)$WORKSPACE_DIR/CLAUDE.md — if an umbrella file exists with a ## Subprojects section, append an entryWORKSPACE_DIRCheck the env var:
echo "${WORKSPACE_DIR:-}"~ if present).AskUserQuestion:"WORKSPACE_DIR isn't set. Default is~/projects/. Use that, or specify a different path?" Options:Use ~/projects/|Use a different path(free-text)
For the rest of this skill, `$WORKSPACE_DIR` is the resolved absolute path (e.g. /Users/alice/projects).
If the user provided a name as an argument, use it. Otherwise ask:
"What's the project name? (lowercase, hyphens for spaces, no special characters — e.g.,tax-tracking,family-recipes)"
Then ask:
"One-line description for the umbrella CLAUDE.md? (e.g., 'Personal tax document tracker' or 'Recipe collection app')"
If $WORKSPACE_DIR/CLAUDE.md doesn't exist, the description is optional — skip if blank.
Must match ^[a-z][a-z0-9-]*$ — starts with lowercase letter, then lowercase alphanumerics and hyphens. If not, ask the user to choose a different name (don't auto-correct, since they may have a specific naming preference).
Run all checks in parallel:
test -d "$WORKSPACE_DIR/<name>" && echo HAS_FOLDER || echo NEW_FOLDER — note whether folder exists; either case is fine.test -f "$WORKSPACE_DIR/<name>/CLAUDE.md" && echo HAS_CLAUDE_MD || echo NO_CLAUDE_MD — note whether the project already has a CLAUDE.md.test -d "$WORKSPACE_DIR/<name>/.git" && echo HAS_GIT || echo NO_GIT — note whether git is already initialized.test -f "$WORKSPACE_DIR/CLAUDE.md" && echo HAS_UMBRELLA || echo NO_UMBRELLA — does the workspace have an umbrella CLAUDE.md to update?test -x "$WORKSPACE_DIR/scripts/fanout-memory.sh" && echo HAS_FANOUT || echo NO_FANOUT — does the optional fan-out helper exist?These are all informational — they tell you which steps below to skip vs. run.
Quickly summarize to the user what you found, e.g.:
"Folder already exists. Has: nothing yet. Will set up: CLAUDE.md stub, memory dir, optionally git. Umbrella file: present, will append entry. Fan-out script: not found, will use plain mkdir for memory dir."
mkdir -p "$WORKSPACE_DIR/<name>"mkdir -p is safe regardless of whether the folder exists.
If the survey reported HAS_CLAUDE_MD, skip this step entirely and tell the user "CLAUDE.md already exists, leaving alone." Never overwrite a CLAUDE.md the user may have already started writing.
If NO_CLAUDE_MD, write $WORKSPACE_DIR/<name>/CLAUDE.md with this template (substituting name and description):
# <Name>
<one-line description from Step 2, or omit if blank>
## Project goals
_(Add as the project takes shape.)_
## Repo layout
_(Document folders/files as the structure emerges.)_
## Conventions
_(Add as patterns appear — naming, error handling, commit style, etc.)_
## External references
_(Links to related repos, docs, dashboards, vendor accounts.)_
## Notes
_(Track ongoing decisions and context here.)_Capitalize the project name appropriately (e.g., tax-tracking → Tax Tracking, BookmarkSync → BookmarkSync). Use sensible title-casing.
Compute the project slug from the absolute project path (this matches how Claude Code derives memory dir names):
SLUG="$(echo "$WORKSPACE_DIR/<name>" | tr '/' '-' | sed 's/^-//')"
MEMORY_DIR="$HOME/.claude/projects/$SLUG/memory"Then:
If `HAS_FANOUT`: run the helper to set up the memory dir with universal-symlink fan-out:
"$WORKSPACE_DIR/scripts/fanout-memory.sh" <name>(The fan-out helper is a user-supplied convention for symlinking universal memories from a workspace-level memory hub into each project's memory dir. If you've never used one, ignore — the fallback below handles you.)
Otherwise: create the memory directory plainly:
mkdir -p "$MEMORY_DIR"
# Seed an empty MEMORY.md if one doesn't exist
if [ ! -f "$MEMORY_DIR/MEMORY.md" ]; then
touch "$MEMORY_DIR/MEMORY.md"
fiShow the user what was created vs. already present.
If the survey reported HAS_GIT, skip the local-init part (git already initialized) and go to 8b to check the remote.
If NO_GIT, ask: "Initialize git for this project? (y/n)"
If the user declines git entirely, skip the rest of Step 8 (no remote, no commit). If yes:
cd "$WORKSPACE_DIR/<name>" && git init -b mainThen create .gitignore with sensible defaults (only if no .gitignore exists yet):
.DS_Store
.env
.env.local
*.log
__pycache__/
node_modules/
.venv/
venv/
build/
dist/
*.pyc
.idea/
.vscode/*.local.jsonIf the user keeps projects on GitHub, the skill can create the remote repo and push an initial scaffold so the project is immediately available from other machines or the web. Skip this for deliberately local-only projects. This step needs the gh CLI authenticated — if it isn't, see Edge cases (skip cleanly, don't error).
First, check for an existing remote (read-only):
git -C "$WORKSPACE_DIR/<name>" remote get-url origin 2>/dev/nullIf origin already points to a github.com[:/]… URL, skip creation and report "GitHub repo already linked." Otherwise, ask:
"Create a GitHub repo (private by default) and push the scaffold? (y/n — choose n for local-only projects.)"
If declined: stop Step 8 here.
If yes:
gh api user --jq .login<name>; offer one override prompt — "GitHub repo name? (default: `<name>`)".--public instead of --private if the user chose public): cd "$WORKSPACE_DIR/<name>" && gh repo create <owner>/<repo> --private --source=. --remote=origin if [ -d "$WORKSPACE_DIR/scripts/web-skills" ]; then
mkdir -p "$WORKSPACE_DIR/<name>/.claude/skills"
cp -R "$WORKSPACE_DIR/scripts/web-skills/"* "$WORKSPACE_DIR/<name>/.claude/skills/"
fi cd "$WORKSPACE_DIR/<name>" && git add -A && git commit -m "Bootstrap <name> scaffold" && git branch -M main && git push -u origin mainThe -u on the first push establishes upstream tracking. (git add -A only picks up the scaffold — CLAUDE.md, .gitignore, .claude/skills/ — since the memory dir lives outside the project folder.)
If NO_UMBRELLA (no $WORKSPACE_DIR/CLAUDE.md exists), skip this step. Don't create an umbrella file unprompted.
If HAS_UMBRELLA, look for a ## Subprojects section in $WORKSPACE_DIR/CLAUDE.md. If absent, skip — don't restructure the user's umbrella file unprompted.
If present, check whether the project is already listed:
grep -q "^- \[<name>/](<name>/) " "$WORKSPACE_DIR/CLAUDE.md" && echo HAS_ENTRY || echo NO_ENTRYIf NO_ENTRY, append a new line in the same format as existing entries:
- [<name>/](<name>/) — <one-line description from Step 2>Keep alphabetical order if the existing list is alphabetical, otherwise append at the end.
Print a tight summary that matches what was actually done. Use ✓ for things created and ⊘ (or "skipped") for things already in place. Example output for a half-existing project:
Project: tax-tracking
WORKSPACE_DIR: /Users/alice/projects
⊘ Folder already existed at /Users/alice/projects/tax-tracking/
✓ Created CLAUDE.md (starter — fill in as you go)
✓ Memory dir set up at ~/.claude/projects/-Users-alice-projects-tax-tracking/memory/ (fallback — no fan-out script found)
✓ Initialized git + .gitignore
✓ GitHub repo (private) created + scaffold pushed → <owner>/tax-tracking
✓ Added entry to umbrella /Users/alice/projects/CLAUDE.md
Next:
Open in VSCode: code /Users/alice/projects/tax-tracking
Or in this session: cd /Users/alice/projects/tax-trackingFor a local-only project (GitHub declined or gh unavailable), show ⊘ Local-only (no GitHub repo) in place of the GitHub line.
If this skill ran in a session launched inside the new folder, note that the freshly written CLAUDE.md and memory dir won't be in context until a fresh window is opened ("Reload Window" doesn't pick them up).
End the skill cleanly — don't start working on the project unless the user asks.
mkdir -p), then proceed.CLAUDE.md, .git, or other user content.mkdir -p creates it.mkdir fallback in Step 7 and tell the user.gh api user fails): warn that the GitHub step is being skipped and the project is local-only for now; do NOT abort the rest of the skill. Suggest gh auth login, then they can re-run to add the remote.gh repo create errors): surface gh's message and ask the user for a different name; don't retry blindly.A pure shell script could do most of this but would feel rigid; the skill lets the agent:
The conversational shape is the point — bootstrap workflows benefit from a moment of judgment per step.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.