diff --git a/.claude/agents/code-reviewer.md b/.claude/agents/code-reviewer.md new file mode 100644 index 000000000..da8e49ada --- /dev/null +++ b/.claude/agents/code-reviewer.md @@ -0,0 +1,25 @@ +You are a code reviewer for a Node.js/TypeScript monorepo (socket-cli). + +Apply the rules from CLAUDE.md sections listed below. Reference the full section in CLAUDE.md for details — these are summaries, not the complete rules. + +**Code Style - File Organization**: kebab-case filenames, @fileoverview headers, node: prefix imports, import sorting order (node → external → @socketsecurity → local → types), fs import pattern. + +**Code Style - Patterns**: UPPER_SNAKE_CASE constants, undefined over null (`__proto__`: null exception), `__proto__`: null first in literals, options pattern with null prototype, { 0: key, 1: val } for entries loops, !array.length not === 0, += 1 not ++, template literals not concatenation, no semicolons, no any types, no loop annotations. + +**Code Style - Functions**: Alphabetical order (private first, exported second), shell: WIN32 not shell: true, never process.chdir(), use @socketsecurity/registry/lib/spawn not child_process. + +**Code Style - Comments**: Default NO comments. Only when WHY is non-obvious. Multi-sentence comments end with periods; single phrases may not. Single-line only. JSDoc: description + @throws only. + +**Code Style - Sorting**: All lists, exports, properties, destructuring alphabetical. Type properties: required first, optional second. + +**Error Handling**: catch (e) not catch (error), double-quoted error messages, { cause: e } chaining. + +**Backward Compatibility**: FORBIDDEN — actively remove compat shims, don't maintain them. + +**Test Style**: Functional tests over source scanning. Never read source files and assert on contents. Verify behavior with real function calls. + +For each file reviewed, report: +- **Style violations** with file:line +- **Logic issues** (bugs, edge cases, missing error handling) +- **Test gaps** (untested code paths) +- Suggested fix for each finding diff --git a/.claude/agents/refactor-cleaner.md b/.claude/agents/refactor-cleaner.md new file mode 100644 index 000000000..019cf41a0 --- /dev/null +++ b/.claude/agents/refactor-cleaner.md @@ -0,0 +1,25 @@ +You are a refactoring specialist for a Node.js/TypeScript monorepo (socket-cli). + +Apply these rules from CLAUDE.md exactly: + +**Pre-Action Protocol**: Before ANY structural refactor on a file >300 LOC, remove dead code, unused exports, unused imports first — commit that cleanup separately before the real work. Multi-file changes: break into phases (≤5 files each), verify each phase. + +**Scope Protocol**: Do not add features, refactor, or make improvements beyond what was asked. Try simplest approach first. + +**Verification Protocol**: Run the actual command after changes. State what you verified. Re-read every file modified; confirm nothing references something that no longer exists. + +**Procedure:** + +1. **Identify dead code**: Grep for unused exports, unreferenced functions, stale imports +2. **Search thoroughly**: When removing anything, search for direct calls, type references, string literals, dynamic imports, re-exports, test files — one grep is not enough +3. **Commit cleanup separately**: Dead code removal gets its own commit before the actual refactor +4. **Break into phases**: ≤5 files per phase, verify each phase compiles and tests pass +5. **Verify nothing broke**: Run `pnpm run check` and `pnpm test` after each phase + +**What to look for:** +- Unused exports (exported but never imported elsewhere) +- Dead imports (imported but never used) +- Unreachable code paths +- Duplicate logic that should be consolidated +- Files >400 LOC that should be split (flag to user, don't split without approval) +- Backward compatibility shims (FORBIDDEN per CLAUDE.md — actively remove) diff --git a/.claude/agents/security-reviewer.md b/.claude/agents/security-reviewer.md new file mode 100644 index 000000000..a56250453 --- /dev/null +++ b/.claude/agents/security-reviewer.md @@ -0,0 +1,26 @@ +You are a security reviewer for Socket Security Node.js repositories. + +Apply these rules from CLAUDE.md exactly: + +**Safe File Operations**: Use safeDelete()/safeDeleteSync() from @socketsecurity/lib/fs. NEVER fs.rm(), fs.rmSync(), or rm -rf. Use os.tmpdir() + fs.mkdtemp() for temp dirs. NEVER use fetch() — use httpJson/httpText/httpRequest from @socketsecurity/lib/http-request. + +**Absolute Rules**: NEVER use npx, pnpm dlx, or yarn dlx. Use pnpm exec or pnpm run with pinned devDeps. + +**Work Safeguards**: Scripts modifying multiple files must have backup/rollback. Git operations that rewrite history require explicit confirmation. + +**Review checklist:** + +1. **Secrets**: Hardcoded API keys, passwords, tokens, private keys in code or config +2. **Injection**: Command injection via shell: true or string interpolation in spawn/exec. Path traversal in file operations. +3. **Dependencies**: npx/dlx usage. Unpinned versions (^ or ~). Missing minimumReleaseAge bypass justification. +4. **File operations**: fs.rm without safeDelete. process.chdir usage. fetch() usage (must use lib's httpRequest). +5. **GitHub Actions**: Unpinned action versions (must use full SHA). Secrets outside env blocks. Template injection from untrusted inputs. +6. **Error handling**: Sensitive data in error messages. Stack traces exposed to users. + +For each finding, report: +- **Severity**: CRITICAL / HIGH / MEDIUM / LOW +- **Location**: file:line +- **Issue**: what's wrong +- **Fix**: how to fix it + +Run `pnpm audit` for dependency vulnerabilities. Run `pnpm run security` for config/workflow scanning. diff --git a/.claude/commands/quality-loop.md b/.claude/commands/quality-loop.md index 88b19480e..ddd59375e 100644 --- a/.claude/commands/quality-loop.md +++ b/.claude/commands/quality-loop.md @@ -1,55 +1,21 @@ -# quality-loop +Run the `/quality-scan` skill and fix all issues found. Repeat until zero issues remain or 5 iterations complete. -Run comprehensive quality scan and automatic issue fixing loop for socket-cli. - -## What it does - -Executes an iterative quality improvement cycle: - -1. Updates dependencies -2. Cleans up repository (removes junk files) -3. Validates code structure -4. Runs specialized quality scans -5. Fixes ALL issues found -6. Commits fixes -7. Repeats until zero issues or 5 iterations - -## Usage - -```bash -/quality-loop -``` - -## Scan types - -- **critical** - Crashes, security, data corruption, auth handling -- **logic** - Algorithm errors, edge cases, validation bugs -- **cache** - Config/token caching correctness -- **workflow** - Build scripts, CI/CD, cross-platform compatibility -- **security** - GitHub Actions security, credential handling -- **documentation** - Command examples, flag accuracy, API docs +**Interactive only** — this command makes code changes and commits. Do not use as an automated pipeline gate. ## Process -The skill will: -- Ask which scans to run (default: all) -- Run dependency updates -- Clean junk files with confirmation -- Execute selected scans sequentially -- Aggregate and deduplicate findings -- Fix issues and commit changes -- Repeat until clean or max iterations - -## Exit conditions - -- ✅ Success: Zero issues found -- ⏹️ Stop: After 5 iterations (prevent infinite loops) - -## Notes - -- Commits fixes with proper git messages -- Skips no issues (fixes architectural problems too) -- Runs tests after each iteration -- Reports progress and statistics - -Use this command to maintain high code quality standards across socket-cli. +1. Run `/quality-scan` skill (all scan types) +2. If issues found: spawn the `refactor-cleaner` agent (see `agents/refactor-cleaner.md`) to fix them, grouped by category +3. Run verify-build (see `_shared/verify-build.md`) after fixes +4. Run `/quality-scan` again +5. Repeat until: + - Zero issues found (success), OR + - 5 iterations completed (stop) +6. Commit all fixes: `fix: resolve quality scan issues (iteration N)` + +## Rules + +- Fix every issue, not just easy ones +- Spawn refactor-cleaner with CLAUDE.md's pre-action protocol: dead code first, then structural changes, ≤5 files per phase +- Run tests after fixes to verify nothing broke +- Track iteration count and report progress diff --git a/.claude/commands/security-scan.md b/.claude/commands/security-scan.md new file mode 100644 index 000000000..6c629680d --- /dev/null +++ b/.claude/commands/security-scan.md @@ -0,0 +1,3 @@ +Run the `/security-scan` skill. This chains AgentShield (Claude config audit) → zizmor (GitHub Actions security) → security-reviewer agent (grading). + +For a quick manual run without the full pipeline: `pnpm run security` diff --git a/.claude/ops/queue.yaml b/.claude/ops/queue.yaml new file mode 100644 index 000000000..804f46ea1 --- /dev/null +++ b/.claude/ops/queue.yaml @@ -0,0 +1,11 @@ +schema_version: 1 + +phase_order: + quality-scan: [env-check, scans, report] + security-scan: [env-check, agentshield, zizmor, grade-report] + updating: [env-check, npm-update, validate, report] + updating-checksums: [env-check, fetch-latest, validate, report] + +# Completed runs are appended here by skills. Prune periodically — +# keep the last 10 entries and delete older ones to avoid unbounded growth. +runs: [] diff --git a/.claude/skills/_shared/env-check.md b/.claude/skills/_shared/env-check.md new file mode 100644 index 000000000..ee2c203d7 --- /dev/null +++ b/.claude/skills/_shared/env-check.md @@ -0,0 +1,27 @@ +# Environment Check + +Shared prerequisite validation for all pipelines. Run at the start of every skill. + +## Steps + +1. Run `git status` to check working directory state +2. Detect CI mode: check for `GITHUB_ACTIONS` or `CI` environment variables +3. Verify `node_modules/` exists (run `pnpm install` if missing) +4. Verify on a valid branch (`git branch --show-current`) + +## Behavior + +- **Clean working directory**: proceed normally +- **Dirty working directory**: warn and continue (most skills are read-only or create their own commits) +- **CI mode**: set `CI_MODE=true` — skills should skip interactive prompts and local-only validation +- **Missing node_modules**: run `pnpm install` before proceeding + +## Queue Tracking + +Write a run entry to `.claude/ops/queue.yaml` with: +- `id`: `{pipeline}-{YYYY-MM-DD}-{NNN}` +- `pipeline`: the invoking skill name +- `status`: `in-progress` +- `started`: current UTC timestamp +- `current_phase`: `env-check` +- `completed_phases`: `[]` diff --git a/.claude/skills/_shared/report-format.md b/.claude/skills/_shared/report-format.md new file mode 100644 index 000000000..3e8cdce7b --- /dev/null +++ b/.claude/skills/_shared/report-format.md @@ -0,0 +1,47 @@ +# Report Format + +Shared output format for all scan and review pipelines. + +## Finding Format + +Each finding: +``` +- **[SEVERITY]** file:line — description + Fix: how to fix it +``` + +Severity levels: CRITICAL, HIGH, MEDIUM, LOW + +## Grade Calculation + +Based on finding severity distribution: +- **A** (90-100): 0 critical, 0 high +- **B** (80-89): 0 critical, 1-3 high +- **C** (70-79): 0 critical, 4+ high OR 1 critical +- **D** (60-69): 2-3 critical +- **F** (< 60): 4+ critical + +## Pipeline HANDOFF + +When a skill completes as part of a larger pipeline (e.g., quality-scan within release), +output a structured handoff block: + +``` +=== HANDOFF: {skill-name} === +Status: {pass|fail} +Grade: {A-F} +Findings: {critical: N, high: N, medium: N, low: N} +Summary: {one-line description} +=== END HANDOFF === +``` + +The parent pipeline reads this to decide whether to proceed (gate check) or abort. + +## Queue Completion + +When the final phase completes, update `.claude/ops/queue.yaml`: +- `status`: `done` (or `failed`) +- `completed`: current UTC timestamp +- `current_phase`: `~` (null) +- `completed_phases`: full list +- `findings_count`: `{critical: N, high: N, medium: N, low: N}` diff --git a/.claude/skills/_shared/security-tools.md b/.claude/skills/_shared/security-tools.md new file mode 100644 index 000000000..9a1f02716 --- /dev/null +++ b/.claude/skills/_shared/security-tools.md @@ -0,0 +1,41 @@ +# Security Tools + +Shared tool detection for security scanning pipelines. + +## AgentShield + +Installed as a pinned devDependency (`ecc-agentshield` in pnpm-workspace.yaml catalog). +Run via: `pnpm exec agentshield scan` +No install step needed — available after `pnpm install`. + +## Zizmor + +Not an npm package. Installed via `pnpm run setup` which downloads the pinned version +from GitHub releases with SHA256 checksum verification (see `external-tools.json`). + +The binary is cached at `.cache/external-tools/zizmor/{version}-{platform}/zizmor`. + +Detection order: +1. `command -v zizmor` (if already on PATH, e.g. via brew) +2. `.cache/external-tools/zizmor/*/zizmor` (from `pnpm run setup`) + +Run via the full path if not on PATH: +```bash +ZIZMOR="$(find .cache/external-tools/zizmor -name zizmor -type f 2>/dev/null | head -1)" +if [ -z "$ZIZMOR" ]; then ZIZMOR="$(command -v zizmor 2>/dev/null)"; fi +if [ -n "$ZIZMOR" ]; then "$ZIZMOR" .github/; else echo "zizmor not installed — run pnpm run setup"; fi +``` + +If not available: +- Warn: "zizmor not installed — run `pnpm run setup` to install" +- Skip the zizmor phase (don't fail the pipeline) + +## Socket CLI + +Optional. Used for dependency scanning in the updating and security-scan pipelines. + +Detection: `command -v socket` + +If not available: +- Skip socket-scan phases gracefully +- Note in report: "Socket CLI not available — dependency scan skipped" diff --git a/.claude/skills/_shared/verify-build.md b/.claude/skills/_shared/verify-build.md new file mode 100644 index 000000000..5dc82c03c --- /dev/null +++ b/.claude/skills/_shared/verify-build.md @@ -0,0 +1,22 @@ +# Verify Build + +Shared build/test/lint validation. Referenced by skills that modify code or dependencies. + +## Steps + +Run in order, stop on first failure: + +1. `pnpm run fix --all` — auto-fix lint and formatting issues +2. `pnpm run check --all` — lint + typecheck + validation (read-only, fails on violations) +3. `pnpm test` — full test suite + +## CI Mode + +When `CI_MODE=true` (detected by env-check), skip this validation entirely. +CI runs these checks in its own matrix (Node 20/22/24 × ubuntu/windows). + +## On Failure + +- Report which step failed with the error output +- Do NOT proceed to the next pipeline phase +- Mark the pipeline run as `status: failed` in `.claude/ops/queue.yaml` diff --git a/.claude/skills/security-scan/SKILL.md b/.claude/skills/security-scan/SKILL.md new file mode 100644 index 000000000..0ba403fea --- /dev/null +++ b/.claude/skills/security-scan/SKILL.md @@ -0,0 +1,82 @@ +--- +name: security-scan +description: Run a multi-tool security scan — AgentShield for Claude config, zizmor for GitHub Actions, and optionally Socket CLI for dependency scanning. Produces an A-F graded security report. +--- + +# Security Scan + +Multi-tool security scanning pipeline for the repository. + +## When to Use + +- After modifying `.claude/` config, settings, hooks, or agent definitions +- After modifying GitHub Actions workflows +- Before releases (called as a gate by the release pipeline) +- Periodic security hygiene checks + +## Prerequisites + +See `_shared/security-tools.md` for tool detection and installation. + +## Process + +### Phase 1: Environment Check + +Follow `_shared/env-check.md`. Initialize a queue run entry for `security-scan`. + +--- + +### Phase 2: AgentShield Scan + +Scan Claude Code configuration for security issues: + +```bash +pnpm exec agentshield scan +``` + +Checks `.claude/` for: +- Hardcoded secrets in CLAUDE.md and settings +- Overly permissive tool allow lists (e.g. `Bash(*)`) +- Prompt injection patterns in agent definitions +- Command injection risks in hooks +- Risky MCP server configurations + +Capture the grade and findings count. + +Update queue: `current_phase: agentshield` → `completed_phases: [env-check, agentshield]` + +--- + +### Phase 3: Zizmor Scan + +Scan GitHub Actions workflows for security issues. + +See `_shared/security-tools.md` for zizmor detection. If not installed, skip with a warning. + +```bash +zizmor .github/ +``` + +Checks for: +- Unpinned actions (must use full SHA, not tags) +- Secrets used outside `env:` blocks +- Injection risks from untrusted inputs (template injection) +- Overly permissive permissions + +Capture findings. Update queue phase. + +--- + +### Phase 4: Grade + Report + +Spawn the `security-reviewer` agent (see `agents/security-reviewer.md`) with the combined output from AgentShield and zizmor. + +The agent: +1. Applies CLAUDE.md security rules to evaluate the findings +2. Calculates an A-F grade per `_shared/report-format.md` +3. Generates a prioritized report (CRITICAL first) +4. Suggests fixes for HIGH and CRITICAL findings + +Output a HANDOFF block per `_shared/report-format.md` for pipeline chaining. + +Update queue: `status: done`, write `findings_count` and final grade. diff --git a/.gitignore b/.gitignore index 554c42e51..240ac97eb 100644 --- a/.gitignore +++ b/.gitignore @@ -74,9 +74,11 @@ yarn-error.log* # ============================================================================ *.log **/build/*.log -**/.claude/* -!**/.claude/skills/ -!**/.claude/commands/ +/.claude/* +!/.claude/agents/ +!/.claude/commands/ +!/.claude/ops/ +!/.claude/skills/ # ============================================================================ # Backup and temporary files diff --git a/CLAUDE.md b/CLAUDE.md index 423e5752d..d723e9006 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -77,6 +77,7 @@ - Always prefer editing existing files - Forbidden to create docs unless requested - Required to do exactly what was asked +- 🚨 **NEVER use `npx`, `pnpm dlx`, or `yarn dlx`** — use `pnpm exec ` for devDep binaries, or `pnpm run