
Brewtools:Text Human
- 4 installs
- 29 repo stars
- Updated August 2, 2026
- kochetkov-ma/claude-brewcode
Helps with ai & agent building tasks.
About
brewtools:text-human is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- brewtools:text-human
- AI & Agent Building
- AI-coding skill
Brewtools:Text Human by the numbers
- 4 all-time installs (skills.sh)
- Ranked #13,372 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kochetkov-ma/claude-brewcode --skill brewtoolstext-humanAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 29 |
| Last updated | August 2, 2026 |
| Repository | kochetkov-ma/claude-brewcode ↗ |
What it does
Helps with ai & agent building tasks.
Files
Text Humanizer
Detect and remove AI-generated artifacts from code and documentation. Process commits, files, or folders with parallel sub-agents.
Language References
| Language | Reference | Load When |
|---|---|---|
| Java/Kotlin | @reference/java.md | *.java, *.kt, *.groovy, Spring, Maven/Gradle |
| TypeScript/JS/React | @reference/typescript.md | *.ts, *.tsx, *.js, *.jsx, Node.js, React |
| Python | @reference/python.md | *.py, Django, FastAPI, Flask |
Multi-language projects: Load ALL relevant references.
---
Argument
First token = scope (required):
| Input | Action |
|---|---|
| None | Use AskUserQuestion: "What to humanize?" Options: "Commit hash (git diff)" / "File path" / "Folder path" |
| Commit hash (7+ hex) | Process all text files from commit |
| File path | Process single file |
| Folder path | Process all files in folder |
| "entire project" | Use AskUserQuestion: "Too broad — specify scope." Options: "Specific folder" / "File pattern (e.g. src/*/.java)" |
Everything after first token = custom prompt (optional). Free-form text, no quotes needed. Overrides or extends default humanization rules for this run. Passed to every sub-agent prompt.
Custom Prompt Handling
1. Parse: split args into scope (first token) and customPrompt (rest) 2. If customPrompt is present, prepend it to every sub-agent Task prompt as:
CUSTOM INSTRUCTIONS (highest priority, override defaults):
<customPrompt>3. Custom prompt wins over default rules on conflict
---
Architecture
Orchestrator -> Detect Language -> Load Reference -> Analyze -> Classify -> Split (3-10 blocks) -> Parallel Task agents -> AggregatePhase 1: Scope Analysis
Commit Mode
Process all text files from commit. No extension filtering: git diff --name-only <hash>^..<hash>
File Inclusion Rules
| Include | Exclude |
|---|---|
Source code (*.java, *.kt, *.py, *.ts, *.js, etc.) | Binary files (*.class, *.pyc, *.exe) |
Config (*.xml, *.yaml, *.yml, *.json, *.toml) | Images (*.png, *.jpg, *.gif, *.ico) |
Docs (*.md, *.txt, *.rst) | Archives (*.zip, *.tar, *.gz) |
Build files (pom.xml, package.json, pyproject.toml) | Generated (target/, build/, dist/, node_modules/) |
SQL (*.sql, *.ddl) | Lock files, IDE files |
Path Mode
find <path> -type f \( -name "*.java" -o -name "*.py" -o -name "*.ts" -o -name "*.js" -o -name "*.md" \) | grep -v -E "(target/|node_modules/|\.git/|build/|dist/|__pycache__/)"Block Count
| Files | Lines | Blocks |
|---|---|---|
| 1-2 | <200 | 1 (direct) |
| 3-5 | <500 | 3 |
| 6-10 | 500-1500 | 5 |
| 11-20 | 1500-3000 | 7 |
| 21+ | 3000+ | 10 |
Single file: process directly without Task delegation.
Phase 2: File Classification
Haiku (Simple)
| Type | Patterns |
|---|---|
| Config | *.properties, *.yaml, *.yml, *.toml, *.ini |
| Data | *.json, *.csv |
| Text | *.txt, *.md |
| Simple SQL | Single CREATE/ALTER, no CTEs/subqueries |
| Small files | <50 lines, no logic |
Sonnet (Complex)
| Type | Patterns |
|---|---|
| Source with logic | Business logic, algorithms |
| Tests | Test files for any framework |
| Complex SQL | CTEs, window functions, JOINs, subqueries |
| Config classes | Framework configuration |
Note: See language-specific references for detailed classification rules.
Phase 3: Block Formation
Group files by type, complexity (avoid mixed haiku/sonnet), line count balance. Keep related files together (same package/directory).
Data files block: YAML, JSON, CSV with comments → haiku for unicode fixes
Phase 4: Parallel Execution
Launch all Task calls in single message for true parallelism.
Task(subagent_type="developer", model="haiku", prompt="> **Context:** BT_PLUGIN_ROOT is available in your context (injected by pre-task.mjs hook).\n\n[CUSTOM_INSTRUCTIONS_IF_ANY]\nBlock 1: [files] [rules] Return JSON")
Task(subagent_type="developer", model="sonnet", prompt="> **Context:** BT_PLUGIN_ROOT is available in your context (injected by pre-task.mjs hook).\n\n[CUSTOM_INSTRUCTIONS_IF_ANY]\nBlock 2: [files] [rules] Return JSON")If custom prompt was provided, prepend to EVERY sub-agent prompt (after the Context line):
> **Context:** BT_PLUGIN_ROOT is available in your context (injected by pre-task.mjs hook).
CUSTOM INSTRUCTIONS (highest priority, override defaults):
<user's custom prompt text>
---<output_format> { "files_processed": N, "changes": [{"file": "path", "removed_comments": N, "fixed_unicode": N, "simplified_docs": N}] } </output_format>
Phase 5: Aggregation
Collect JSON results from all agents → merge statistics → generate unified report.
---
<humanization_rules>
AI Artifacts (Universal)
| Pattern | Action |
|---|---|
// Added by AI, // Claude suggestion, // AI-generated, // Generated by | Delete |
# Added by AI, # Claude suggestion | Delete |
/* Suggested by */ | Delete block |
AI-invented issue numbers (BUG-001, FIX-123, ISSUE-1) | Delete |
| Unicode long dash (U+2014) | Replace → -- |
| Unicode arrows (→, ←, ⇒) | Replace → ->, <-, => |
| Unicode bullets (•, ◦) | Replace → - or * |
| Unicode quotes (" " ' ') | Replace → " or ' |
Real vs Fake Issue References
Keep project-specific ticket patterns (INTELDEV-XXXXX, JIRA-XXXXX, GH-XXX). Remove generic AI-invented patterns (BUG-001, FIX-123, ISSUE-42).
Documentation Cleanup (General Principles)
| Remove | Keep |
|---|---|
| Private/internal function docs | Public API documentation |
| Test file documentation | Complex algorithm explanation |
| Obvious classes/functions (name = purpose) | Non-obvious behavior/side effects |
| Trivial parameter docs (restates name) | @throws/Raises with conditions |
| Trivial return docs (restates function) | External API contracts |
Key Rule: Never convert block docs to inline comments. Delete unnecessary docs entirely; for useful descriptions with trivial params, strip params and keep description.
Comments (Universal)
Keep WHY, remove WHAT.
| Remove | Keep |
|---|---|
// Initialize the list | // Retry 3x due to flaky external API |
// Loop through items | // Uses UTC to match database timezone |
// Check if null | // Thread-safe: synchronized on class lock |
Stale // TODO: refactor this | // HACK: workaround for <issue-link> |
Formatting (Universal)
| Issue | Fix |
|---|---|
/* single line */ | // single line or # single line |
| 3+ blank lines | Max 2 |
| Trailing whitespace | Remove |
| Mixed tabs/spaces | Spaces |
</humanization_rules>
---
File Type Rules
| Type | Rules |
|---|---|
| Source code | Full doc cleanup per language reference |
| Test files | Remove all docs, keep test descriptions |
| SQL/XML | Preserve structural comments |
| Markdown | Remove AI disclosures, fix unicode |
| YAML/Properties | Fix unicode, keep config explanations |
| JSON/CSV | Check for comments with unicode, usually skip |
YAML/Data Files
Check for unicode in comments. Section comments are valuable.
| Action | Example |
|---|---|
| FIX | # Lane 90001→10001 → # Lane 90001->10001 |
| KEEP | # ===== VAN loads for test ===== |
| SKIP | Pure data without comments |
SQL/XML Comments
Structural comments are valuable. Analyze neighboring files first.
| Action | Example |
|---|---|
| KEEP | Section headers -- ============ TABLES ============ |
| KEEP | Block separators <!-- ===== Mappers ===== --> |
| KEEP | Column/field documentation |
| REMOVE | Exact duplicates, AI markers |
---
Custom Prompt Mode
Custom prompt overrides or extends default rules. Use for:
- Restricting scope: "only remove AI artifacts, don't touch docs"
- Adding rules: "also remove all @author tags"
- Excluding files: "skip test files"
- Style reference: "use style from src/main/Service.java as reference"
Output Format
## Humanization Report
### Execution Summary
| Metric | Value |
|--------|-------|
| Total files | N |
| Blocks | M |
| Haiku/Sonnet | X/Y |
### Block Results
[Per-block tables with file metrics]
### Totals
| Metric | Count |
|--------|-------|
| Files processed | N |
| Comments removed | X |
| Docs simplified | Y |
| Unicode fixed | Z |Best Practices
- Load language reference first
- Process all commit files (include yaml/data files)
- Check yaml for unicode (comments may have arrows)
- Preserve valuable comments (they add context)
- Skip binaries (avoid corruption)
- Honor style reference if provided
- Keep public API docs
- Group files by complexity
- Launch agents in parallel
Error Handling
| Error | Action |
|---|---|
| Agent timeout | Continue with other blocks |
| File read error | Skip, note in report |
| Binary file | Skip, note in report |
| No changes | Report "No humanization required" |
Examples
/text-human 3be67487 # Commit - all files
/text-human src/main/java/MyService.java # Single file
/text-human src/main/java/services/ # Folder
/text-human 3be67487 don't touch docs on public records # Commit + custom prompt
/text-human src/ only remove AI artifacts and fix unicode # Path + custom prompt
/text-human 3be67487 also remove all @author tags # Commit + extra ruleMIT License
Copyright (c) 2025-2026 Maxim Kochetkov (kochetkov-ma)
https://github.com/kochetkov-ma/claude-brewcode
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Text Humanizer
Detects and removes AI-generated artifacts from code and documentation -- comments like // Added by AI, fake issue numbers, unicode characters, and trivial docs that just restate the function name. Works on commits, files, or folders with parallel sub-agents.
Quick Start
/brewtools:text-human <commit-hash|path> [custom instructions]Modes
| Mode | How to trigger | What it does |
|---|---|---|
| Commit | text-human 3be67487 | Processes all text files changed in the given commit via git diff |
| Single file | text-human src/main/java/MyService.java | Processes one file directly (no sub-agent delegation) |
| Folder | text-human src/main/java/services/ | Finds all source/config/doc files in the folder, splits into parallel blocks |
| Custom prompt | text-human <scope> <instructions> | Everything after the first token becomes custom instructions that override defaults |
| Interactive | text-human (no args) | Asks what to humanize: commit hash, file path, or folder path |
Examples
Good Usage
# Clean up all files from a recent AI-assisted commit
/brewtools:text-human 3be67487
# Humanize a single service class after AI pair-programming
/brewtools:text-human src/main/java/com/example/OrderService.java
# Process an entire package
/brewtools:text-human src/main/java/services/
# Commit cleanup but preserve public API docs
/brewtools:text-human 3be67487 don't touch docs on public records
# Only fix unicode and AI markers, leave everything else
/brewtools:text-human src/ only remove AI artifacts and fix unicode
# Add an extra rule on top of defaults
/brewtools:text-human 3be67487 also remove all @author tagsCommon Mistakes
# Too broad -- will ask you to narrow the scope
/brewtools:text-human entire project
# Running on hand-written code that has no AI artifacts -- wastes time, no changes made
/brewtools:text-human src/legacy/HandCraftedUtils.java
# Pointing at generated/build output -- these files are excluded automatically
/brewtools:text-human target/classes/What It Changes
| Category | Removed / Fixed | Example |
|---|---|---|
| AI comment markers | // Added by AI, // Claude suggestion, // AI-generated, // Generated by | Deleted entirely |
| Fake issue numbers | BUG-001, FIX-123, ISSUE-42 | Deleted (real project tickets like JIRA-1234 are kept) |
| Unicode long dashes | U+2014 -- | Replaced with -- |
| Unicode arrows | ->, <-, => | Replaced with ->, <-, => |
| Unicode bullets | Bullet characters | Replaced with - or * |
| Unicode smart quotes | Curly quotes | Replaced with " or ' |
| Trivial docs | Javadoc/docstring that restates the method name | Deleted |
| Obvious comments | // Initialize the list, // Loop through items | Deleted |
| Formatting noise | 3+ blank lines, trailing whitespace, mixed tabs/spaces | Normalized |
What It Keeps
| Preserved | Why |
|---|---|
"Why" comments (// Retry 3x due to flaky external API) | Explain non-obvious behavior |
| Public API documentation | External contracts matter |
Real issue references (INTELDEV-12345, JIRA-456) | Project-specific tickets |
Structural comments in SQL/YAML (-- ===== TABLES =====) | Section organization |
@throws / Raises with conditions | Documents failure modes |
| Complex algorithm explanations | Not trivially obvious |
Output
Produces a Humanization Report at the end with:
| Metric | Description |
|---|---|
| Total files | Number of files scanned |
| Blocks | How many parallel blocks were used |
| Haiku / Sonnet split | Simple files (config, data) vs complex files (logic, tests) |
| Comments removed | Count per file |
| Docs simplified | Count per file |
| Unicode fixed | Count per file |
Files are edited in place. No backup files are created -- use git to revert if needed.
Tips
- Start with a commit hash after an AI-assisted session -- it automatically picks up all changed files including YAML and config that you might forget.
- Use custom instructions to narrow scope:
only remove AI artifacts and fix unicodeskips the doc cleanup entirely if you want to keep verbose docs. - Language references are loaded automatically based on file extensions -- Java/Kotlin, TypeScript/JS, and Python each have dedicated cleanup rules.
- Single files skip sub-agent delegation and process directly, so small scopes are fast even without parallelism.
Documentation
Full docs: text-human
Java/Kotlin Reference
Language-specific rules for text-human skill
File Classification
Haiku (Simple)
| Type | Patterns |
|---|---|
| Resources | logback*.xml, pom.xml, build.gradle |
| Small DTOs | *.java <50 lines, no logic |
| Properties | application.properties, bootstrap.yml |
Sonnet (Complex)
| Type | Patterns |
|---|---|
| Business logic | *.java, *.kt with logic |
| Tests | *Test.java, *Spec.kt, *IT.java |
| Config classes | *Configuration.java, *Config.java |
| Controllers | *Controller.java, *RestController.java |
| Services | *Service.java, *ServiceImpl.java |
| Repositories | *Repository.java, *Dao.java |
| Mapper XML | MyBatis/JOOQ dynamic SQL |
Classification Logic
| Extension | Condition | Result |
|---|---|---|
| java, kt | Contains @Test, @Configuration, @Service, @Repository | COMPLEX |
| java, kt | <50 lines, no nested classes | SIMPLE |
| java, kt | Otherwise | COMPLEX |
| groovy | Spock tests, Gradle scripts | COMPLEX |
---
JavaDoc Cleanup
Remove JavaDoc from: private methods, test files, obvious classes. Keep logic description, remove trivial @param/@return.
| Remove | Keep |
|---|---|
| All private/package-private methods | Public API docs with non-obvious behavior |
All test files (*Test.java, *Spec.kt, test helpers) | @DisplayName on test methods |
| Obvious DTOs/Entities (name describes purpose) | Complex business logic explanation |
| All @param (restates param name) | @throws with specific conditions |
| All @return (restates method name) | Non-obvious side effects |
| Class doc when class name is self-explanatory | External API contracts |
Logic vs Parameters Rule
NEVER convert JavaDoc `/ /` to inline `//` comment.* Two rules:
1. JavaDoc is unnecessary (private method, obvious class) → DELETE entirely, no replacement 2. JavaDoc has useful description but trivial @param/@return → strip @param/@return, keep description as single-line /** ... */
// BEFORE - useful description + trivial @param/@return:
/**
* Converts USD to target currency. Returns unchanged if USD.
* @param amount the amount
* @param currency the currency
* @return converted amount
*/
// AFTER - keep description as single-line JavaDoc, strip @param/@return:
/** Converts USD to target currency. Returns unchanged if USD. */
BigDecimal convertCurrency(BigDecimal amount, CurrencyCode currency) { }
// KEEP @param - explains non-obvious behavior:
/**
* @param hasExtraStops true=include ALL loads, false/null=only WITHOUT extra stops
*/Private Methods
// REMOVE - private methods don't need JavaDoc:
/** Validates the filter. */
private boolean isValidFilter(Filter f) { }
/** Builds full condition. */
private Condition buildFullCondition() { }
/** Rounds value to scale. @param value the value @param scale the scale */
private Double roundToScale(double value, int scale) { }Obvious DTOs/Entities
// REMOVE - class name is self-explanatory:
/** Filter DTO for rates history queries. */
@Value @Builder
public class RatesHistoryFilter { }
/** Entity for rate history data. */
@Value @Builder
public class HistoryRateEntity { }
// KEEP - adds non-obvious context:
/** Cached for 1 hour. Thread-safe via copy-on-write. */
public class CompanyCache { }Test Files
Remove all JavaDoc from: test classes (*Test.java, *Spec.kt), test helpers (*Data.java, *Requests.java, *Fixtures.java), any file in src/test/.
// REMOVE - test class:
/** Test class for LoadsHistoryRepository. */
class LoadsHistoryRepositoryTest {
/** Tests filtering by company ID. */
@Test void testFilterByCompanyId() { }
}
// REMOVE - test helper classes:
/** Expected data for rates stats tests. */
@UtilityClass
public class RatesStatsExpectedData {
/** Factory method for expected stats. */
public static Stats expected() { }
}
// CORRECT - no JavaDoc, clear method names:
class LoadsHistoryRepositoryTest {
@Test
@DisplayName("Should filter loads by company ID")
void filterByCompanyId() {
// GIVEN
// WHEN
// THEN
}
}
@UtilityClass
public class RatesStatsExpectedData {
public static Stats expected() { }
}---
Comments
| Remove | Keep |
|---|---|
// Initialize the list | // Retry 3x due to flaky external API |
// Loop through items | // Uses UTC to match database timezone |
// Check if null | // Thread-safe: synchronized on class lock |
Stale // TODO: refactor this | // HACK: workaround for JDK-12345 |
Preserve all BDD comments: // GIVEN, // WHEN, // THEN, // AND
---
Issue References
// REMOVE - AI-invented numbers:
// BUG-001 fix: ...
// FIX-123: ...
// ISSUE-42: ...
// KEEP - real ClickUp/Jira tickets:
// INTELDEV-19207: ...
// Workaround for JIRA-12345Keep project-specific ticket patterns (INTELDEV-XXXXX, JIRA-XXXXX). Remove generic patterns (BUG-001, FIX-123).
---
Pre-Completion Checklist
| Check | Rule |
|---|---|
| [ ] | Private methods: no JavaDoc on private/protected/package-private methods |
| [ ] | Test files: no JavaDoc on *Test.java, *Spec.kt, or any file in src/test/ |
| [ ] | Test helpers: no JavaDoc on *Data.java, *Requests.java, *Fixtures.java |
| [ ] | Obvious DTOs: no JavaDoc if class name is self-explanatory |
| [ ] | Trivial @param: no @param id the id or similar restating param name |
| [ ] | Trivial @return: no @return that restates method name |
| [ ] | Lombok: no docs on @Value, @Data, @Builder classes unless non-obvious |
Scan Pattern
# Semantic search queries for grepai_search:
grepai_search("private methods with javadoc")
grepai_search("trivial param documentation")
grepai_search("test helper classes")
grepai_search("DTO classes with javadoc")
# Fallback grep patterns:
grep -n "^\s*/\*\*" <file> // Find all JavaDoc
grep -n "private.*{" <file> // Find private methodsFiles to Double-Check
Repository classes (private helper methods), Service classes (internal methods), Test helper classes (not ending in Test), DTOs/Entities (redundant class-level JavaDoc).
---
File Inclusion
| Include | Exclude |
|---|---|
*.java, *.kt, *.groovy | *.class, *.jar, *.war |
pom.xml, build.gradle, build.gradle.kts | target/, build/, .gradle/ |
*.xml (Spring, MyBatis) | Generated sources |
*.properties, *.yaml, *.yml | IDE files (.idea/, *.iml) |
Python Reference
Language-specific rules for text-human skill
File Classification
Haiku (Simple)
| Type | Patterns |
|---|---|
| Config | *.toml, pyproject.toml, setup.cfg |
| Requirements | requirements*.txt, constraints.txt |
| Constants | constants.py, config.py (pure values) |
| Init files | __init__.py (imports only) |
| Type stubs | *.pyi |
Sonnet (Complex)
| Type | Patterns |
|---|---|
| Business logic | *.py with classes/functions |
| Tests | test_*.py, *_test.py, conftest.py |
| CLI | cli.py, __main__.py |
| APIs | *_api.py, routes.py, views.py |
| Models | models.py, schemas.py |
| Services | *_service.py, services/*.py |
Classification Logic
| Extension | Condition | Result |
|---|---|---|
| py | Contains def test_, @pytest, class Test | COMPLEX |
| py | <30 lines, only imports/constants | SIMPLE |
| py | Has classes with methods | COMPLEX |
| py | Otherwise | COMPLEX |
| pyi | Type stubs | SIMPLE |
---
Docstring Cleanup
Remove docstrings from: private methods, test files, obvious functions. Keep public API docs.
| Remove | Keep |
|---|---|
Private methods (_method, __method) | Public API |
Test files (test_*.py) | Complex algorithms |
| Obvious functions (name = purpose) | Non-obvious side effects |
| Trivial Args restating name | Raises with conditions |
| Trivial Returns restating function | Examples with edge cases |
| Class docstring when name is clear | Type explanations for Any/Union |
Docstring Styles
Handle all common styles (Google, NumPy, Sphinx):
# REMOVE - trivial Google style:
def get_user(user_id: int) -> User:
"""Get user by ID.
Args:
user_id: The user ID.
Returns:
The user object.
"""
# CORRECT - no docstring needed:
def get_user(user_id: int) -> User:
...
# KEEP - adds context:
def get_user(user_id: int) -> User:
"""Fetches from cache first, falls back to DB. Returns None if not found."""Private Methods
# REMOVE - private methods don't need docstrings:
def _validate_input(self, data: dict) -> bool:
"""Validate the input data."""
def __calculate_hash(self, value: str) -> int:
"""Calculate hash for value."""
# CORRECT - no docstrings:
def _validate_input(self, data: dict) -> bool:
...
def __calculate_hash(self, value: str) -> int:
...Classes
# REMOVE - obvious class:
class UserRepository:
"""Repository for user operations."""
class OrderService:
"""Service for order management."""
# CORRECT - no docstring:
class UserRepository:
...
# KEEP - non-obvious behavior:
class RateLimiter:
"""Token bucket algorithm. Thread-safe. Tokens refill every 100ms."""Dunder Methods
# REMOVE - dunder methods are well-known:
def __init__(self, name: str):
"""Initialize with name."""
def __str__(self) -> str:
"""Return string representation."""
def __len__(self) -> int:
"""Return length."""
# CORRECT - no docstrings on dunders:
def __init__(self, name: str):
self.name = name
# EXCEPTION - keep if non-standard behavior:
def __eq__(self, other) -> bool:
"""Compares by ID only, ignores other fields."""---
Comments
| Remove | Keep |
|---|---|
# Initialize variable | # Workaround for Python 3.9 bug |
# Loop through items | # Must be eager (not lazy) for thread safety |
# Check if None | # noqa: E501 - URL cannot be split |
# TODO: refactor | # HACK: see https://bugs.python.org/12345 |
Type Comments
# REMOVE - use type hints instead:
x = [] # type: List[int]
y = None # type: Optional[str]
# CORRECT - inline type hints:
x: list[int] = []
y: str | None = None
# KEEP - when type hints not possible:
# type: ignore[arg-type] # mypy false positiveNoqa Comments
| Action | Example |
|---|---|
| KEEP | # noqa: E501 - long URL (with reason) |
| KEEP | # type: ignore[override] (mypy) |
| REMOVE | # noqa without code or reason |
| REVIEW | Multiple noqa in one file (code smell) |
---
Test Files
Remove all docstrings from: test files, fixtures, conftest.py.
# REMOVE - test file:
class TestUserService:
"""Tests for UserService."""
def test_create_user(self):
"""Test creating a user."""
# CORRECT - no docstrings:
class TestUserService:
def test_create_user(self):
# Arrange
# Act
# Assert
...
# REMOVE - fixtures:
@pytest.fixture
def mock_user():
"""Create mock user for tests."""
# CORRECT:
@pytest.fixture
def mock_user():
...---
Pre-Completion Checklist
| Check | Rule |
|---|---|
| [ ] | No docstrings on private methods (_method) |
| [ ] | No docstrings on dunder methods (unless non-standard) |
| [ ] | No docstrings on test files |
| [ ] | No trivial Args/Returns in docstrings |
| [ ] | No type comments when type hints work |
| [ ] | # noqa comments have explanations |
Scan Pattern
# Semantic search:
grepai_search("private methods with docstrings")
grepai_search("trivial docstring parameters")
grepai_search("test file documentation")
# Fallback grep:
grep -n '"""' <file> # Find docstrings
grep -n "def _" <file> # Find private methods---
File Inclusion
| Include | Exclude |
|---|---|
*.py, *.pyi | __pycache__/ |
*.toml, *.cfg, *.ini | *.pyc, *.pyo |
*.txt (requirements) | .venv/, venv/, .env/ |
*.md, *.rst | dist/, build/, *.egg-info/ |
Makefile, Dockerfile | .tox/, .pytest_cache/ |
TypeScript/JavaScript/React Reference
Language-specific rules for text-human skill
File Classification
Haiku (Simple)
| Type | Patterns |
|---|---|
| Config | *.json, tsconfig.json, package.json, .eslintrc.* |
| Constants | constants.ts, config.ts (pure exports) |
| Types only | *.d.ts, types.ts, interfaces.ts |
| Styles | *.css, *.scss, *.less |
Sonnet (Complex)
| Type | Patterns |
|---|---|
| Components | *.tsx, *.jsx with logic |
| Hooks | use*.ts, use*.tsx |
| Services | *Service.ts, *Api.ts |
| Tests | *.test.ts, *.spec.ts, *.test.tsx |
| Utilities | utils/*.ts with business logic |
| State | *Slice.ts, *Store.ts, *Context.tsx |
Classification Logic
| Extension | Condition | Result |
|---|---|---|
| ts, tsx | Contains describe(, it(, test( | COMPLEX |
| ts, tsx | <30 lines, only types/interfaces | SIMPLE |
| ts, tsx | React component with hooks/effects | COMPLEX |
| js, jsx | Otherwise | COMPLEX |
| json | Pure data | SIMPLE (often skip) |
---
JSDoc Cleanup
Remove JSDoc from: private functions, test files, obvious components. Keep public API docs.
| Remove | Keep |
|---|---|
| Internal/private functions | Exported public API |
Test files (*.test.ts, *.spec.ts) | Complex utility functions |
| Obvious components (name = purpose) | Non-obvious side effects |
Trivial @param restating name | @throws, @deprecated |
Trivial @returns restating function name | @example with usage |
@type when TypeScript infers | Generic type explanations |
JSDoc vs TypeScript
Prefer TypeScript types over JSDoc when both exist:
// REMOVE - redundant JSDoc with TS types:
/**
* @param {string} name - The user name
* @param {number} age - The user age
* @returns {User} The created user
*/
function createUser(name: string, age: number): User { }
// KEEP - only TS types:
function createUser(name: string, age: number): User { }
// KEEP - adds context beyond types:
/** Creates user and sends welcome email. Throws if email fails. */
function createUser(name: string, age: number): User { }React Components
// REMOVE - obvious component:
/** Button component that renders a button. */
const Button: FC<ButtonProps> = ({ onClick, children }) => { }
/** User profile card component. */
const UserCard: FC<UserCardProps> = ({ user }) => { }
// KEEP - non-obvious behavior:
/** Debounces input by 300ms. Calls onChange only after user stops typing. */
const DebouncedInput: FC<InputProps> = ({ onChange }) => { }
// KEEP - complex props explanation:
/**
* @param renderItem - Custom renderer, receives (item, index, isLast)
* @param onEndReached - Called when scroll reaches 80% of list
*/
const VirtualList: FC<ListProps> = ({ renderItem, onEndReached }) => { }Hooks
// REMOVE - obvious hook:
/** Hook that manages loading state. */
const useLoading = () => { }
/** Hook for user data. */
const useUser = (id: string) => { }
// KEEP - non-obvious behavior:
/** Fetches on mount + refetches every 30s. Pauses when tab inactive. */
const usePolling = (url: string, interval = 30000) => { }
/** Returns memoized callback. Deps auto-tracked via proxy. */
const useAutoCallback = <T extends Function>(fn: T): T => { }---
Comments
| Remove | Keep |
|---|---|
// Initialize state | // Workaround for React 18 strict mode |
// Map over items | // Must be sync for Safari compatibility |
// Check if null | // Intentionally not memoized - cheap to compute |
// TODO: fix later | // HACK: workaround for webpack/webpack#12345 |
ESLint/TSLint Comments
| Action | Example |
|---|---|
| KEEP | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| KEEP | /* eslint-disable */ at file top with reason |
| REMOVE | // eslint-disable without explanation |
| REVIEW | Multiple disables in one file (code smell) |
Preserve
// @ts-expect-errorwith explanation// @ts-ignore(but prefer @ts-expect-error)- Region comments
// #region,// #endregion
---
Test Files
Remove all JSDoc from: test files, test utilities, mocks, fixtures.
// REMOVE - test file:
/** Tests for UserService. */
describe('UserService', () => {
/** Should create user with valid data. */
it('creates user', () => { })
})
// CORRECT - no JSDoc, clear descriptions:
describe('UserService', () => {
it('creates user with valid data', () => {
// Arrange
// Act
// Assert
})
})
// REMOVE - test utilities:
/** Creates mock user for tests. */
export const createMockUser = () => { }
// CORRECT:
export const createMockUser = () => { }---
Pre-Completion Checklist
| Check | Rule |
|---|---|
| [ ] | No JSDoc on internal/unexported functions |
| [ ] | No JSDoc on test files (*.test.ts, *.spec.ts) |
| [ ] | No redundant JSDoc when TS types exist |
| [ ] | No JSDoc on obvious React components |
| [ ] | ESLint disables have explanations |
| [ ] | No @param/@returns restating obvious info |
Scan Pattern
# Semantic search:
grepai_search("jsdoc on private functions")
grepai_search("redundant type annotations")
grepai_search("test file documentation")
# Fallback grep:
grep -n "/\*\*" <file> // Find JSDoc
grep -n "^const.*=" <file> // Find functions---
File Inclusion
| Include | Exclude |
|---|---|
*.ts, *.tsx, *.js, *.jsx | *.d.ts (generated) |
*.mjs, *.cjs | node_modules/ |
*.json (with comments) | dist/, build/, .next/ |
*.md, *.mdx | coverage/ |
| Config files | Lock files (*.lock, *-lock.json) |