Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution.

MITAuto-check passed

Install Clean

skills CLI
$ npx skills add catlog22/Claude-Code-Workflow --skill clean -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install catlog22/Claude-Code-Workflow clean --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/catlog22/Claude-Code-Workflow.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.codex/skills/clean .claude/skills/clean && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
clean
GitHub stars
2.1k
Token cost
~3.2k tokens
SKILL.md length
200 words
Files
1
Skills in repo
82
Repo updated
First seen
Licence
MIT

At a glance

Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution.

  • Works in 5 steps: Initialization → Mainline Detection → Drift Discovery → …
  • SKILL.md covers Overview, Target Cleanup, Execution Process and Implementation, plus 5 more sections
  • Calls git

What it does

Clean is an agent skill from catlog22/Claude-Code-Workflow. Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution. Supports targeted cleanup and confirmation.

Its SKILL.md is about 3.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: JSON-driven multi-agent cadence-team development framework with intelligent CLI orchestration (Gemini/Qwen/Codex), context-first architecture, and automated workflow execution. The licence is MIT.

Example prompts

  • “/clean”

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Initialization
  2. Mainline Detection
  3. Drift Discovery
  4. Confirmation
  5. Execution

What it can do on your machine

Read from SKILL.md and the folder at commit 07491b0. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • git

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Clean loads about 3.2k tokens when it runs. Until then it costs about 36 tokens; SKILL.md has 200 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~36
When it runs · the whole SKILL.md, loaded when a task matches
~3.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from catlog22/Claude-Code-Workflow at commit 07491b0, republished under its MIT licence (© catlog22). 200 words, ~3,164 tokens.

Download SKILL.mdSave it as .claude/skills/clean/SKILL.md (or your agent's skills folder).
name
clean
description
Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution. Supports targeted cleanup and confirmation.
argument-hint
[--dry-run] [--focus=<area>]

Workflow Clean Command

Overview

Evidence-based intelligent cleanup command. Systematically identifies stale artifacts through mainline analysis, discovers drift, and safely removes unused sessions, documents, and dead code.

Core workflow: Detect Mainline → Discover Drift → Confirm → Stage → Execute

Target Cleanup

Focus area: $FOCUS (or entire project if not specified) Mode: $ARGUMENTS

  • --dry-run: Preview cleanup without executing
  • --focus: Focus area (module or path)

Execution Process

Phase 0: Initialization
   ├─ Parse arguments (--dry-run, FOCUS)
   ├─ Setup session folder
   └─ Initialize utility functions

Phase 1: Mainline Detection
   ├─ Analyze git history (30 days)
   ├─ Identify core modules (high commit frequency)
   ├─ Map active vs stale branches
   └─ Build mainline profile

Phase 2: Drift Discovery (Subagent)
   ├─ spawn_agent with cli-explore-agent role
   ├─ Scan workflow sessions for orphaned artifacts
   ├─ Identify documents drifted from mainline
   ├─ Detect dead code and unused exports
   └─ Generate cleanup manifest

Phase 3: Confirmation
   ├─ Validate manifest schema
   ├─ Display cleanup summary by category
   ├─ request_user_input: Select categories and risk level
   └─ Dry-run exit if --dry-run

Phase 4: Execution
   ├─ Validate paths (security check)
   ├─ Stage deletion (move to .trash)
   ├─ Update manifests
   ├─ Permanent deletion
   └─ Report results

Implementation

Phase 0: Initialization
Step 0: Determine Project Root

检测项目根目录,确保 .workflow/ 产物位置正确:

bash
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)

优先通过 git 获取仓库根目录;非 git 项目回退到 pwd 取当前绝对路径。 存储为 {projectRoot},后续所有 .workflow/ 路径必须以此为前缀。

javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()

// Parse arguments
const args = "$ARGUMENTS"
const isDryRun = args.includes('--dry-run')
const focusMatch = args.match(/FOCUS="([^"]+)"/)
const focusArea = focusMatch ? focusMatch[1] : "$FOCUS" !== "$" + "FOCUS" ? "$FOCUS" : null

// Session setup
const dateStr = getUtc8ISOString().substring(0, 10)
const sessionId = `clean-${dateStr}`
const sessionFolder = `${projectRoot}/.workflow/.clean/${sessionId}`
const trashFolder = `${sessionFolder}/.trash`
const projectRoot = bash('git rev-parse --show-toplevel 2>/dev/null || pwd').trim()

bash(`mkdir -p ${sessionFolder}`)
bash(`mkdir -p ${trashFolder}`)

// Utility functions
function fileExists(p) {
  try { return bash(`test -f "${p}" && echo "yes"`).includes('yes') } catch { return false }
}

function dirExists(p) {
  try { return bash(`test -d "${p}" && echo "yes"`).includes('yes') } catch { return false }
}

function validatePath(targetPath) {
  if (targetPath.includes('..')) return { valid: false, reason: 'Path traversal' }

  const allowed = ['.workflow/', '.claude/rules/tech/', 'src/']
  const dangerous = [/^\//, /^C:\\Windows/i, /node_modules/, /\.git$/]

  if (!allowed.some(p => targetPath.startsWith(p))) {
    return { valid: false, reason: 'Outside allowed directories' }
  }
  if (dangerous.some(p => p.test(targetPath))) {
    return { valid: false, reason: 'Dangerous pattern' }
  }
  return { valid: true }
}

Phase 1: Mainline Detection
javascript
// Check git repository
const isGitRepo = bash('git rev-parse --git-dir 2>/dev/null && echo "yes"').includes('yes')

let mainlineProfile = {
  coreModules: [],
  activeFiles: [],
  activeBranches: [],
  staleThreshold: { sessions: 7, branches: 30, documents: 14 },
  isGitRepo,
  timestamp: getUtc8ISOString()
}

if (isGitRepo) {
  // Commit frequency by directory (last 30 days)
  const freq = bash('git log --since="30 days ago" --name-only --pretty=format: | grep -v "^$" | cut -d/ -f1-2 | sort | uniq -c | sort -rn | head -20')

  // Parse core modules (>5 commits)
  mainlineProfile.coreModules = freq.trim().split('\n')
    .map(l => l.trim().match(/^(\d+)\s+(.+)$/))
    .filter(m => m && parseInt(m[1]) >= 5)
    .map(m => m[2])

  // Recent branches
  const branches = bash('git for-each-ref --sort=-committerdate refs/heads/ --format="%(refname:short)" | head -10')
  mainlineProfile.activeBranches = branches.trim().split('\n').filter(Boolean)
}

Write(`${sessionFolder}/mainline-profile.json`, JSON.stringify(mainlineProfile, null, 2))

Phase 2: Drift Discovery
javascript
let exploreAgent = null

try {
  // Launch cli-explore-agent
  exploreAgent = spawn_agent({
    agent_type: "cli_explore_agent",
    message: `
## TASK ASSIGNMENT

### MANDATORY FIRST STEPS
1. Read: ${projectRoot}/.workflow/project-tech.json (if exists)

## Task Objective
Discover stale artifacts for cleanup.

## Context
- Session: ${sessionFolder}
- Focus: ${focusArea || 'entire project'}

## Discovery Categories

### 1. Stale Workflow Sessions
Scan: ${projectRoot}/.workflow/active/WFS-*, ${projectRoot}/.workflow/archives/WFS-*, ${projectRoot}/.workflow/.lite-plan/*, ${projectRoot}/.workflow/.debug/DBG-*
Criteria: No modification >7 days + no related git commits

### 2. Drifted Documents
Scan: .claude/rules/tech/*, ${projectRoot}/.workflow/.scratchpad/*
Criteria: >30% broken references to non-existent files

### 3. Dead Code
Scan: Unused exports, orphan files (not imported anywhere)
Criteria: No importers in import graph

## Output
Write to: ${sessionFolder}/cleanup-manifest.json

Format:
{
  "generated_at": "ISO",
  "discoveries": {
    "stale_sessions": [{ "path": "...", "age_days": N, "reason": "...", "risk": "low|medium|high" }],
    "drifted_documents": [{ "path": "...", "drift_percentage": N, "reason": "...", "risk": "..." }],
    "dead_code": [{ "path": "...", "type": "orphan_file", "reason": "...", "risk": "..." }]
  },
  "summary": { "total_items": N, "by_category": {...}, "by_risk": {...} }
}
`
  })

  // Wait with timeout handling (4-step cascade)
  let result = wait_agent({ timeout_ms: 1800000 })

  if (result.timed_out) {
    // Status probe
    followup_task({ target: exploreAgent, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
    const status = wait_agent({ timeout_ms: 180000 })  // 3 min
    if (status.timed_out) {
      // Force finalize
      followup_task({ target: exploreAgent, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
      const forced = wait_agent({ timeout_ms: 180000 })  // 3 min
      if (forced.timed_out) {
        close_agent({ target: exploreAgent })
        throw new Error('Agent timeout')
      }
    }
  }

  if (!fileExists(`${sessionFolder}/cleanup-manifest.json`)) {
    throw new Error('Manifest not generated')
  }

} finally {
  if (exploreAgent) close_agent({ target: exploreAgent })
}

Phase 3: Confirmation
javascript
// Load and validate manifest
const manifest = JSON.parse(Read(`${sessionFolder}/cleanup-manifest.json`))

// Display summary
console.log(`
## Cleanup Discovery Report

| Category | Count | Risk |
|----------|-------|------|
| Sessions | ${manifest.summary.by_category.stale_sessions} | ${getRiskSummary('sessions')} |
| Documents | ${manifest.summary.by_category.drifted_documents} | ${getRiskSummary('documents')} |
| Dead Code | ${manifest.summary.by_category.dead_code} | ${getRiskSummary('code')} |

**Total**: ${manifest.summary.total_items} items
`)

// Dry-run exit
if (isDryRun) {
  console.log(`
**Dry-run mode**: No changes made.
Manifest: ${sessionFolder}/cleanup-manifest.json
  `)
  return
}

// User confirmation
const selection = functions.request_user_input({
  questions: [
    {
      header: "清理类别",
      id: "categories",
      question: "Which categories to clean?",
      options: [
        { label: "Sessions", description: `${manifest.summary.by_category.stale_sessions} stale sessions` },
        { label: "Documents", description: `${manifest.summary.by_category.drifted_documents} drifted docs` },
        { label: "Dead Code", description: `${manifest.summary.by_category.dead_code} unused files` }
      ]
    },
    {
      header: "风险级别",
      id: "risk",
      question: "Risk level?",
      options: [
        { label: "Low only(Recommended)", description: "Safest — only clearly stale items" },
        { label: "Low + Medium", description: "Includes likely unused" },
        { label: "All", description: "Aggressive" }
      ]
    }
  ]
})  // BLOCKS (wait for user response)

Phase 4: Execution
javascript
const selectedCategory = selection.answers.categories.answers[0]
const selectedRisk = selection.answers.risk.answers[0]

const riskFilter = {
  'Low only(Recommended)': ['low'],
  'Low + Medium': ['low', 'medium'],
  'All': ['low', 'medium', 'high']
}[selectedRisk]

// Collect items to clean
const items = []
if (selectedCategory === 'Sessions') {
  items.push(...manifest.discoveries.stale_sessions.filter(s => riskFilter.includes(s.risk)))
}
if (selectedCategory === 'Documents') {
  items.push(...manifest.discoveries.drifted_documents.filter(d => riskFilter.includes(d.risk)))
}
if (selectedCategory === 'Dead Code') {
  items.push(...manifest.discoveries.dead_code.filter(c => riskFilter.includes(c.risk)))
}

const results = { staged: [], deleted: [], failed: [], skipped: [] }

// Validate and stage
for (const item of items) {
  const validation = validatePath(item.path)
  if (!validation.valid) {
    results.skipped.push({ path: item.path, reason: validation.reason })
    continue
  }

  if (!fileExists(item.path) && !dirExists(item.path)) {
    results.skipped.push({ path: item.path, reason: 'Not found' })
    continue
  }

  try {
    const trashTarget = `${trashFolder}/${item.path.replace(/\//g, '_')}`
    bash(`mv "${item.path}" "${trashTarget}"`)
    results.staged.push({ path: item.path, trashPath: trashTarget })
  } catch (e) {
    results.failed.push({ path: item.path, error: e.message })
  }
}

// Permanent deletion
for (const staged of results.staged) {
  try {
    bash(`rm -rf "${staged.trashPath}"`)
    results.deleted.push(staged.path)
  } catch (e) {
    console.error(`Failed: ${staged.path}`)
  }
}

// Cleanup empty trash
bash(`rmdir "${trashFolder}" 2>/dev/null || true`)

// Report
console.log(`
## Cleanup Complete

**Deleted**: ${results.deleted.length}
**Failed**: ${results.failed.length}
**Skipped**: ${results.skipped.length}

### Deleted
${results.deleted.map(p => `- ${p}`).join('\n') || '(none)'}

${results.failed.length > 0 ? `### Failed\n${results.failed.map(f => `- ${f.path}: ${f.error}`).join('\n')}` : ''}

Report: ${sessionFolder}/cleanup-report.json
`)

Write(`${sessionFolder}/cleanup-report.json`, JSON.stringify({
  timestamp: getUtc8ISOString(),
  results,
  summary: {
    deleted: results.deleted.length,
    failed: results.failed.length,
    skipped: results.skipped.length
  }
}, null, 2))

Session Folder

{projectRoot}/.workflow/.clean/clean-{YYYY-MM-DD}/
├── mainline-profile.json     # Git history analysis
├── cleanup-manifest.json     # Discovery results
├── cleanup-report.json       # Execution results
└── .trash/                   # Staging area (temporary)

Risk Levels

RiskDescriptionExamples
LowSafe to deleteEmpty sessions, scratchpad files
MediumLikely unusedOrphan files, old archives
HighMay have dependenciesFiles with some imports

Security Features

FeatureProtection
Path ValidationWhitelist directories, reject traversal
Staged DeletionMove to .trash before permanent delete
Dangerous PatternsBlock system dirs, node_modules, .git

Iteration Flow

First Call (/prompts:clean):
   ├─ Detect mainline from git history
   ├─ Discover stale artifacts via subagent
   ├─ Display summary, await user selection
   └─ Execute cleanup with staging

Dry-Run (/prompts:clean --dry-run):
   ├─ All phases except execution
   └─ Manifest saved for review

Focused (/prompts:clean FOCUS="auth"):
   └─ Discovery limited to specified area

Error Handling

SituationAction
No git repoUse file timestamps only
Agent timeoutRetry once with prompt, then abort
Path validation failSkip item, report reason
Manifest parse errorAbort with error
Empty discoveryReport "codebase is clean"

Now execute cleanup workflow with focus: $FOCUS

© catlog22, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .codex/skills/clean of catlog22/Claude-Code-Workflow.

Open the folder on GitHubat commit 07491b0

Compare with similar skills

Clean next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Clean compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Clean this skillcatlog22/Claude-Code-Workflow2.1k—~3.2kAutomated safety check: PassMIT
Artifacts Buildernexu-io/open-design100k—~347Automated safety check: PassApache-2.0
Web Artifacts Builderanthropics/skills180k40 repos~769Automated safety check: PassApache-2.0
Cleanupsimstudioai/sim30k—~1.4kAutomated safety check: PassApache-2.0
Stale Worktree Cleanuptrycompai/comp2k—~1.8kAutomated safety check: NotesAGPL-3.0
Web Artifacts Buildernexu-io/open-design100k—~337Automated safety check: PassApache-2.0

Similar skills

  • Artifacts Builder

    nexu-io/open-design

    Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui).

    100k GitHub stars~347 tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Web Artifacts Builder

    anthropics/skills

    Official

    Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.

    180k GitHub starsUsed in 40 repos~769 tokens
    Frontend & DesignAuto-check passed
  • Cleanup

    simstudioai/sim

    Run all code quality skills — effects, memo, callbacks, state, React Query, emcn design review, url-state, comments, and test-audit — analyzing in parallel, then applying fixes sequentially

    30k GitHub stars~1.4k tokensUpdated today
    DevelopmentAuto-check passed
  • A skill your agent uses when cleaning up old git worktrees, removing worktrees whose branches have merged or been abandoned, or dropping orphaned compdev Postgres databases.

    2k GitHub stars~1.8k tokensUpdated 5 days ago
    DevelopmentAuto-check: notes
  • Web Artifacts Builder

    nexu-io/open-design

    Build complex claude.ai HTML artifacts with React and Tailwind.

    100k GitHub stars~337 tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Lovable Cleanup

    sickn33/agentic-awesome-skills

    Audits and strips Lovable scaffolding from Vite + React projects — removes lovable-tagger, swaps placeholder assets, prunes unused Radix deps, cleans generated docs, and neutralizes stale…

    47k GitHub starsUsed in 1 repo~3.7k tokens
    DevelopmentAuto-check: notes

More from catlog22/Claude-Code-Workflow

All 82 skills in this repo
  • Prompt Generator

    catlog22/Claude-Code-Workflow

    Generate or convert Claude Code prompt files — command orchestrators, skill files, agent role definitions, or style conversion of existing files.

    2.1k GitHub starsUsed in 1 repo~4.7k tokens
    Auto-check: notes
  • Ccw Help

    catlog22/Claude-Code-Workflow

    CCW command help system. An agent skill from catlog22/Claude-Code-Workflow.

    2.1k GitHub stars~2.5k tokensUpdated 3 mo ago
    Auto-check passed
  • Team Ultra Analyze

    catlog22/Claude-Code-Workflow

    Deep collaborative analysis team skill. An agent skill from catlog22/Claude-Code-Workflow.

    2.1k GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check: notes
  • Brainstorm

    catlog22/Claude-Code-Workflow

    Unified brainstorming skill with dual-mode operation — auto mode (framework generation, parallel multi-role analysis, cross-role synthesis) and single role analysis.

    2.1k GitHub stars~4.8k tokensUpdated 3 mo ago
    Auto-check: notes
  • Ccw Chain

    catlog22/Claude-Code-Workflow

    Chain-based CCW workflow orchestrator. An agent skill from catlog22/Claude-Code-Workflow.

    2.1k GitHub stars~1.1k tokensUpdated 3 mo ago
    Auto-check: notes
  • Delegation Check

    catlog22/Claude-Code-Workflow

    Check workflow delegation prompts against agent role definitions for content separation violations.

    2.1k GitHub stars~2.8k tokensUpdated 3 mo ago
    Auto-check: notes

Questions about Clean

What does Clean do?

Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution. Clean is an agent skill from catlog22/Claude-Code-Workflow. Intelligent code cleanup with mainline detection, stale artifact discovery, and safe execution.

How do I install Clean in Claude Code?

Run `npx skills add catlog22/Claude-Code-Workflow --skill clean -a claude-code`. Or copy the skill folder (.codex/skills/clean in catlog22/Claude-Code-Workflow) into .claude/skills/clean in your project. Claude Code loads it when a task matches its description.

How do I install Clean in Codex?

Run `npx skills add catlog22/Claude-Code-Workflow --skill clean -a codex`. Or copy the skill folder (.codex/skills/clean in catlog22/Claude-Code-Workflow) into .agents/skills/clean in your project. Codex loads it when a task matches its description.

Can I use Clean in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add catlog22/Claude-Code-Workflow --skill clean -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/clean, .gemini/skills/clean, .github/skills/clean and .opencode/skills/clean in your project.

What does Clean need to run?

Going by SKILL.md and its folder, Clean needs the command-line tools its instructions call (git).

Does Clean access the network?

SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Clean safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Clean use?

Clean is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Clean use?

About 3.2k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Clean?

Skills that share tags, products or a category with Clean: Artifacts Builder (nexu-io/open-design, 100k stars), Web Artifacts Builder (anthropics/skills, 180k stars), Cleanup (simstudioai/sim, 30k stars) and Stale Worktree Cleanup (trycompai/comp, 2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Clean?

catlog22 (a GitHub user) maintains it in catlog22/Claude-Code-Workflow, which has 2,130 GitHub stars. The repository holds 82 skills in this directory. The repository was last updated on June 18, 2026.

Source: catlog22/Claude-Code-Workflow on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.