SLOPSHOPPER

redact

Masks credential-shaped strings in a Read tool result before the model reads it.

newguard
★ 12v0.1.0MITupdated 2026-09-24thkt/dotclaude/mods/redact
A shopper browsing a rack in a slop shop
README

Claude AI Configuration

A comprehensive configuration system for Claude AI with custom commands, development principles, and workflow optimizations.

📌 日本語版

🎯 Overview

This repository contains personal configurations for Claude AI, including:

  • Custom slash commands for systematic development workflows (27 skills)
  • Specialized AI agents for code review, generation, and analysis (28 agents)
  • Core AI operation principles and development best practices
  • Quality pipeline hooks (guardrails, formatter, gates) and the unwired reviews command
  • Japanese language support

📁 Structure

.claude/
├── CLAUDE.md              # Main configuration (AI reads this)
├── README.md              # This file - Quick start guide
├── rules/                 # Rule definitions
│   ├── core/             # Core AI operation principles
│   ├── conventions/      # Documentation conventions
│   └── development/      # Development patterns & methodologies
├── skills/               # Skill-based knowledge modules (27 skills)
├── agents/               # Specialized AI agents (28 agents)
│   ├── critics/          # Finding challengers (devils-advocate)
│   ├── enhancers/        # Code enhancers & simplifiers
│   ├── explorers/        # Codebase exploration agents
│   ├── generators/       # Test & snapshot generation
│   ├── resolvers/        # Build error resolvers
│   └── reviewers/        # Code review agents (18 reviewers)
├── docs/                  # Design docs & guides (DRs under decisions/)
├── hooks/                 # Pre/Post tool-use hooks
├── output-styles/         # Output style definitions
├── .claude-plugin/        # Plugin marketplace config
└── .ja/                   # Japanese translations

🚀 Quick Start

Option 1: Install as Claude Code Plugin (Recommended)

This repository is available as a Claude Code plugin, allowing you to easily install specific workflow sets:

  1. Add this repository as a marketplace:
   /plugin marketplace add thkt/dotclaude
  1. Browse available plugins:
   /plugin
  1. Install the plugin:
   /plugin install build
Available Plugins
  • build: Self-contained development workflow toolkit. Installing it clones the whole repository once, so every skill, agent, and workflow loads under the build: namespace. File an issue with /issue and hand its number to the build workflow. Build creates a draft PR after Load / Revalidate / Branch / Code / Cleanup / Verify / Ship. Humans invoke /audit and /polish separately on the draft PR. Bundles the planning skills (/think, /research, /slice, /outcome), the reviewer and critic agents, the code / audit / polish / shake / assert / adrift workflows, the git skills (/commit, /checkout, /pr), and /dr, /census.

Option 2: Manual Installation (Full Configuration)

For using this as your personal .claude configuration:

  1. Clone this repository to your home directory:
   git clone https://github.com/thkt/dotclaude.git ~/.claude
  1. Or if you already have a .claude directory, back it up first:
   mv ~/.claude ~/.claude.backup
   git clone https://github.com/thkt/dotclaude.git ~/.claude

Note: Manual installation applies all skills, agents, rules, and personal configuration. Plugin installation also clones the whole repository, but Claude Code loads only its skills, agents, and workflows; personal CLAUDE.md, rules/, and settings.json are not applied as rules or settings. A skill that cites rules/ reads the copy inside the plugin.

📦 Dependencies & Setup

Sandbox Feature (Optional but Recommended)

Claude Code's sandbox feature provides secure command execution with automatic permission handling, reducing approval fatigue while maintaining safety.

System Requirements
  • macOS or Linux (Windows not yet supported)
  • Node.js with npm/npx
  • ripgrep (typically pre-installed)
  • jq (required by the current hooks): brew install jq
Setup
# 1. Install sandbox runtime
npm install -g @anthropic-ai/sandbox-runtime

# 2. Verify installation
srt --version

# 3. Enable in Claude Code
# Run this command in Claude Code session:
/sandbox
# Select option 1: "Sandbox BashTool, with auto-allow in accept edits mode"
What it does
  • Restricts file system access to allowed directories
  • Controls network access via proxy
  • Auto-executes safe commands in sandbox
  • Requests approval only when sandbox restrictions are hit
Configuration (optional)

Create ~/.srt-settings.json for custom settings:

{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "excludedCommands": ["docker"],
    "network": {
      "allowLocalBinding": true,
      "httpProxyPort": 8080
    }
  }
}

The build workflow runs gh inside the sandbox. On macOS with the sandbox enabled, gh's TLS verification requires sandbox.enableWeakerNetworkIsolation: true in ~/.claude/settings.json. Without it, the build fails at the issue-fetch step.

Hook Tools (Recommended)

Quality pipeline hooks wired in settings.json run automatically during Claude Code sessions to catch lint errors, format code, and enforce quality gates. The install command includes reviews, but settings.json does not wire it, so it does not run automatically.

brew tap thkt/tap
brew install guardrails formatter reviews gates
ToolHookTimingRole
guardrailsPreToolUseBefore Write/EditLint (oxlint) + security checks
formatterPostToolUseAfter Write/EditAuto-format (oxfmt)
reviewsNot wiredNo automatic runStatic-analysis command
gatesPostToolUseAfter Write/Edit/BashQuality gates (knip, tsgo, madge)

Per-project configuration is done via .claude/tools.json. See thkt/tap for details.

External CLI Tools (Optional)

Some commands use external CLI tools for data source integration. codegraph needs codegraph init per repository to create .codegraph/ before use.

ToolRequired ByPurposeInstall
gh/issue, /pr, /preview, /buildGitHub API accessbrew install gh && gh auth login
scout/research, use-cli-scout skillWeb search, page fetch, GitHub repo exploration, Slack fetchbrew install thkt/tap/scout
codegraph/research, use-cli-codegraph skillSymbol-level structure queries (callers, impact)npm i -g @colbymchenry/codegraph

Slack reading: scout fetch <slack-url> reads any Slack message/thread URL directly. No additional setup needed if scout is configured.

Autonomous Iteration

/code can run as an autonomous multi-turn loop via the native /goal command (Claude Code 2.1.139+). No plugin install is required.

/goal all tests pass and lint is clean

Wrap a /code session in /goal <condition>; Claude continues until a fast model judges the condition met from the conversation.

📝 Available Commands

See the complete command reference:

🔄 Standard Workflows

Feature Development

/research → /think → /issue → build workflow → /audit · /polish

Bug Investigation & Fix

/research → /fix

🌏 Language Support

  • AI Processing: English internally
  • User Output: Japanese (configurable)
  • Documentation: README.md and docs/*.md are available in English and Japanese; the seven docs/wiki/*.md files are English-only

🛠️ Key Features

Core AI Principles

  • Safety First: File deletion uses trash (~/.Trash/), destructive operations require confirmation
  • User Authority: Your instructions are the ultimate authority
  • Output Verifiability: Confirm exact formats by reading files, never assert about unread code, and stop when a knowledge gap blocks critical verification

Development Approach

  • Occam's Razor: Choose the simplest solution that works
  • Progressive Enhancement: Build simple, enhance gradually
  • TDD/RGRC: Red-Green-Refactor-Commit cycle for reliable code

Full details: PRINCIPLES.md

📚 Documentation

Core Documentation

Development Guides

🤝 Contributing

Feel free to fork this repository and customize it for your needs. Pull requests for improvements are welcome!

📜 License

MIT License - Feel free to use and modify as needed.

👤 Author

thkt

Source 2 files
hooks/register.ts 15 lines
1import type { On } from "claude-code";
2
3import { maskedRead } from "./redact.ts";
4
5export function register(on: On) {
6  on("tool.call", { tool: "Read" }, async ($, e, next) => {
7    const r = await next(e);
8    if (e.tool !== "Read" || r.deny !== undefined || r.isError) return r;
9    const masked = maskedRead(r.result);
10    // Returning r keeps core's own messages (ref), which still carry the raw content.
11    // Only a hook's own { result } makes core re-map the output for the model.
12    return masked === null ? r : { result: masked, context: r.context };
13  });
14}
15
hooks/redact.ts 36 lines
1// Credential shapes whose prefix or framing makes a false match unlikely. A generic
2// high-entropy detector is left out on purpose: it would mask hashes and ids the model
3// needs to read.
4const PATTERNS: readonly { kind: string; pattern: RegExp }[] = [
5  { kind: "private-key", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g },
6  { kind: "anthropic", pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}/g },
7  { kind: "openai", pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g },
8  { kind: "github", pattern: /\b(?:gh[pousr]_[A-Za-z0-9]{36,}|github_pat_[A-Za-z0-9_]{60,})/g },
9  { kind: "aws-access-key", pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g },
10  { kind: "slack", pattern: /\bxox[abprs]-[A-Za-z0-9-]{10,}/g },
11  { kind: "google-api", pattern: /\bAIza[0-9A-Za-z_-]{35}\b/g },
12];
13
14/** The text with every credential-shaped match replaced, and how many were replaced. */
15export function redact(text: string): { text: string; count: number } {
16  let count = 0;
17  let out = text;
18  for (const { kind, pattern } of PATTERNS) {
19    out = out.replace(pattern, () => {
20      count++;
21      return `[REDACTED:${kind}]`;
22    });
23  }
24  return { text: out, count };
25}
26
27type ReadResult = { type: string; file?: { content?: unknown } };
28
29/** The Read result with its text content masked, or null when nothing needed masking. */
30export function maskedRead<R extends ReadResult>(result: R): R | null {
31  const content = result.file?.content;
32  if (result.type !== "text" || typeof content !== "string") return null;
33  const { text, count } = redact(content);
34  return count === 0 ? null : { ...result, file: { ...result.file, content: text } };
35}
36