agentsclimarketplace

Scan projects

Skill jasonChen0604/codebase-to-portfolio/skills/scan-projects

Turn your entire codebase history into a portfolio-ready tech profile — with any AI coding agent (Claude Code, Codex, Copilot, Cursor).

Install
npx -y skills add jasonChen0604/codebase-to-portfolio --skill scan-projects

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 29 days oldThe repository was created 29 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Scan all valid software projects (including Docker/docker-compose projects) under a configured directory and output a Markdown list for manual filtering. Triggers when the user says "scan projects", "list my projects", "find all projects", "掃描專案", or "列出所有專案".

SKILL.md

5.2 KB, as published. Nobody here has run it

Scan Projects Skill

Goal

Scan all valid software projects under the configured scan_root and output a Markdown report (projects-list.md) for manual filtering.

Step 0: Read config

Read profile.config.json from the current working directory. If missing, tell the user to copy examples/profile.config.example.json to profile.config.json and fill it in, then stop.

  • scan_root (default ~/project if not set) — expand ~ to $HOME
  • A user-specified path argument overrides scan_root for this run

Definition of a Valid Software Project

A directory is considered a valid project root if any of the following markers exist (file or directory):

package.json, Cargo.toml, go.mod, pyproject.toml, requirements.txt, setup.py,
Makefile, pom.xml, build.gradle, CMakeLists.txt, .git, composer.json, Gemfile,
Dockerfile, dockerfile, docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml

Execution Steps

Step 1: Confirm scan root directory

  • Use scan_root from config (or the user-specified override)
  • Verify the directory exists with ls

Step 2: Execute scan (recursive, max 4 levels)

  • If the current directory matches any marker → treat as project root, do not recurse further
  • If no match → continue scanning subdirectories, max depth of 4
  • Skip the following subdirectory names: node_modules, .git, .venv, __pycache__, dist, build, packages

Use the following bash script:

BASE_DIR="<scan_root, ~ expanded to $HOME>"
MAX_DEPTH=4
MARKERS=(
  "package.json" "Cargo.toml" "go.mod" "pyproject.toml" "requirements.txt"
  "setup.py" "Makefile" "pom.xml" "build.gradle" "CMakeLists.txt" ".git"
  "composer.json" "Gemfile" "Dockerfile" "dockerfile"
  "docker-compose.yml" "docker-compose.yaml" "compose.yml" "compose.yaml"
)

is_project_root() {
  local dir="$1"
  for marker in "${MARKERS[@]}"; do
    [[ -e "$dir/$marker" ]] && return 0
  done
  return 1
}

collect_projects() {
  local dir="$1"
  local depth="$2"
  [[ "$depth" -gt "$MAX_DEPTH" ]] && return

  if is_project_root "$dir"; then
    echo "$dir"
    return
  fi

  while IFS= read -r subdir; do
    collect_projects "$subdir" $(( depth + 1 ))
  done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d \
    ! -name "node_modules" ! -name ".git" ! -name ".venv" \
    ! -name "__pycache__" ! -name "dist" ! -name "build" ! -name "packages")
}

collect_projects "$BASE_DIR" 0

Step 3: Collect additional metadata

For each valid project, gather:

  • Type tags based on matched markers (multi-select):
    • Node.js (package.json)
    • Python (requirements.txt / pyproject.toml / setup.py)
    • Docker (Dockerfile / dockerfile)
    • Docker Compose (docker-compose.yml / docker-compose.yaml / compose.yml / compose.yaml)
    • Go (go.mod), Rust (Cargo.toml), Java (pom.xml / build.gradle)
    • C/C++ (CMakeLists.txt), PHP (composer.json), Ruby (Gemfile)
    • Git (.git)
  • Description: read description from package.json, or first non-heading line of README.md (max 80 chars)
  • Last commit: git -C <dir> log -1 --format="%ar" 2>/dev/null (show for non-Git projects)
  • Doc file: check if <dir>/<doc_filename> exists (config doc_filename, default CLAUDE.md) — show ✅ if yes, ❌ if no
  • Version: if the doc file exists, read skill_version from frontmatter (e.g. "2.0"); show if missing or field not present

Step 3.5: Diff against existing projects-list.md

Read the existing projects-list.md (if it exists) and parse all Path values already present:

  • Build a set of existing paths from every table row
  • From the scanned results, keep only paths NOT already in the file — these are new projects
  • If no new projects found → report "no new projects found" and stop (do not modify the file)

Step 4: Append new projects to projects-list.md

Do not overwrite or rewrite the existing file. Only append new rows.

  1. Read the current highest # index from the existing table
  2. For each new project (not already listed), append a new table row using the same format:
| N | ✅ | project-name | ~/project/... | Type | last commit | ✅/❌ | version | description |
  1. Update the header line > Found N valid projects to reflect the new total count
  2. All existing rows, Active values, descriptions, and ordering are untouched

New projects default to ✅ for "Active".

Step 5: Report results

  • Tell the user how many new projects were added
  • List the new project names
  • Remind the user they can set "Active" to ❌ for projects they don't want to track

Notes

  • A directory that matches a marker is treated as a project root — do not recurse into it (avoids duplicate listing of submodules)
  • Max scan depth is 4 levels from the root
  • Existing rows are never modified — only new rows are appended
  • If the root is not the default, remember the user-specified path for this session

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.