project-patterns — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited project-patterns (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.
Single-process Node.js CLI tool. No server, no database, no external service dependencies (except npm registry for version checks with 5s timeout). Pure filesystem operations — reads templates, writes scaffolded files, merges with existing user files.
Layer diagram:
CLI Entry (index.js)
└── Commands (commands/*.js) — orchestration, user flow
├── Prompts (prompts/*.js) — Inquirer interactions, isolated from logic
├── Core (core/*.js) — business logic, no user interaction*
├── Generators (generators/*.js) — produce file content dynamically
├── Data (data/*.js) — constants, catalogs, registries
└── Utils (utils/*.js) — pure helpers, no side effects*Exception: merger.js calls promptHookConflict() directly — pragmatic compromise.
Key invariant: Commands orchestrate between prompts and core. Prompts never call core directly. Core never prompts the user (except merger.js).
agent-routing.js, file-categorizer.js, claude-md-merge.js).test.js suffix (merger.test.js, agent-routing-integration.test.js)buildSettingsJson, mergeSettingsPermissionsAndHooks)UNIVERSAL_AGENTS, AGENT_CATALOG)Layer-based (not feature-based):
src/
├── index.js # CLI entry point (Commander.js setup)
├── commands/ # One file per CLI command (init, upgrade, status, backup, restore, diff)
├── core/ # Business logic: scaffolder, merger, detector, backup, config, file-categorizer
├── prompts/ # Inquirer prompt definitions: project-type, tech-stack, agent-selection, conflicts
├── generators/ # Dynamic content builders (agent-routing.js)
├── data/ # Constants: agents.js (catalogs), agent-registry.js (routing metadata)
└── utils/ # Pure helpers: display.js, file.js, hash.js, time.js, npm.js
templates/ # User-facing template files (quality matters — these ship to users)
├── settings/ # 16 language-specific + base + docker JSON templates
├── agents/ # universal/ (5) + optional/ (18 across 6 categories)
├── commands/ # 10 slash command templates
└── skills/ # universal/ (9) + templates/ (3 placeholder skills)
tests/
├── commands/ # Tests mirror src/ structure
├── core/
├── prompts/
├── utils/
└── fixtures/ # Test projects: fresh-project, existing-project, workflow-projectWhere new things go:
src/commands/ + register in src/index.jstemplates/agents/ + entry in agents.js + entry in agent-registry.jstemplates/skills/ + scaffolder reference + hash computationsrc/utils/ (must be pure, no side effects)All user-facing output goes through display.*:
import * as display from '../utils/display.js';
display.success('Done!');
display.error('Something failed');
display.newline();Never use console.log for user output.
Always operate on parsed objects, never on stringified JSON:
// CORRECT
const settings = JSON.parse(templateContent);
settings.permissions.allow.push(...newPermissions);
const output = JSON.stringify(settings, null, 2);
// WRONG — will break on special characters
const output = templateString.replace('{{permissions}}', newPermissions);User JSON files may have shell-escaped braces from zsh heredoc artifacts:
// Pass 1: try raw JSON.parse
// Pass 2: strip \{ → { and \} → }, then JSON.parse
// Both fail: throw with clear error messageDon't simplify to a single pass.
.claude/workflow-ref/<path> when same-name file exists (even if content is identical). Preserves the original filename so diff against the live file is trivial. Kept out of .claude/commands/ and .claude/agents/ to avoid being discovered as a phantom command or agent.templates/agents/optional/{category}/AGENT_CATALOG in src/data/agents.jssrc/data/agent-registry.jsNo central error handler. Try/catch at the command level:
// Pattern in every command file
try {
// ... main work
} catch (err) {
spinner?.fail('Human-readable failure message');
display.error(err.message);
process.exit(1);
}sudoNo retry logic anywhere. No circuit breakers. Operations are local and idempotent — if something fails, the user re-runs the command.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.