Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pick and clean comments

Use reforge comments pick to review comments, and reforge comments clean to preview or apply explicitly selected removals. Both commands run locally. They support Rust, JavaScript/JSX and TypeScript/TSX, including .mjs, .cjs, .mts and .cts. Vue, other languages and files with syntax/encoding errors are not editable and appear in the skipped-file receipts when discovered.

Pick a review set

reforge comments pick .
reforge comments pick . --candidates
reforge comments pick src --contains 'legacy' --kind line
reforge comments pick . --output json --output-file comments.json

The inventory contains the original comment text, path, line range, enclosing or following symbol when available, nearby source, protection reasons and review hints. Consecutive standalone ordinary line comments are one group: selecting a matching line selects the whole group. This preserves continuation lines of directives, licenses and rationale. Inspect the group before cleaning. Inline comments and block comments are separate items.

Review hints cover empty/separator comments, repeated text within one file, known template placeholders and possible commented-out code. They are heuristics, not proof of uselessness or obsolescence. Reforge does not infer whether an arbitrary explanation is stale and does not use a model to rewrite comments.

Selection flags:

FlagMeaning
--contains TEXTCase-sensitive literal substring of the original comment
--text TEXTExact trimmed body without comment delimiters; multiline bodies retain line breaks
--id IDExact ID from the inventory
--kind line|block|documentationLimit comment kind
--candidatesLimit to comments with review hints

Repeated values within one selector are ORed. Different selectors are ANDed. Empty text selectors are rejected. IDs include the file content hash: any change to that file makes its old IDs stale, which produces an error instead of silently selecting another comment. JSON inventory/plan output is deterministic for an unchanged root and configuration. Byte ranges refer to decoded UTF-8 without its BOM, not byte offsets in a UTF-16 file.

The commands discover reforge.toml and honor its [scope] settings. The scope flags --config, --include-hidden, --include-generated, --no-gitignore, --exclude-tests and repeatable --ignore-path are also available. Generated folders such as target, node_modules, dist and build are excluded by default. --ignore-path matches relative paths/directory prefixes, not globs. Excluded files are outside the inventory; discovered but unsupported or invalid files are listed as skipped. Other analyzer configuration is validated but does not enable or disable comment inventory or cleanup.

Preview and apply

# Preview: source files stay unchanged.
reforge comments clean . --text 'your code here'

# Apply the selected ordinary comment removals in one command.
reforge comments clean . --text 'your code here' --apply

# Or select an exact comment group from pick.
reforge comments clean . --id comment-<full-id>

Clean requires --all, --id, --text or --contains. --candidates alone does not authorize deletion. Documentation comments, license notices, recognized tool instructions (including reforge:, @ts-ignore, ESLint and source-map markers), TODO/FIXME debt, generated notices and recognized safety/rationale statements are protected in text/ID selection mode, even if the selector matches them. Protection is conservative and marker-based; a plain comment with important meaning but no recognized marker still requires human judgment.

The default output is a unified diff on stdout. A summary and skipped-file receipts go to stderr. A zero-match or fully protected selection produces no changes. Applying a selection skips protected comments and reports their count. To see their specific reasons, use pick with the same selectors.

To remove every comment, including protected documentation, licenses, TODO/FIXME and tool directives:

# Preview every removal in the configured scope.
reforge comments clean . --all

# One-command application.
reforge comments clean . --all --apply

# Or save and replay the full-removal plan.
reforge comments clean . --all --output json --output-file all-comments.json
reforge comments clean . --plan all-comments.json --apply

--all is mutually exclusive with text/ID/kind/candidate selectors and --plan. It still honors scope exclusions and supported languages. Unsupported or invalid files are reported as skipped; strings containing comment delimiters remain unchanged. Hash checks, syntax checks and write recovery still apply. Deleting documentation or tool directives can change generated docs, lint/type-check results or other tooling behavior even when non-comment syntax is unchanged. The summary explicitly identifies all-comments mode, including when replaying a saved plan. protected_comments counts comments retained by protection, so it is zero in this mode.

Save a plan when review and application happen separately:

reforge comments clean . --text 'your code here' \
  --output json --output-file cleanup.json
reforge comments clean . --plan cleanup.json
reforge comments clean . --plan cleanup.json --apply

Pass the original workspace path when replaying a plan from a different working directory. A plan cannot be combined with new selection or scope flags. Plans use version 1 for protected text/ID selection and version 2 with removal_mode: "all" for full removal. Existing version 1 plans retain their original protection behavior. These are not schema 27 reports or workflow artifacts. The plan records selected IDs, file hashes, original edit text and replacement ranges. Application validates the workspace root, hashes, selection, the recorded removal mode and recomputed edits; arbitrary modified replacements are rejected. To narrow a plan, generate another plan with the desired IDs rather than editing its ranges or replacement text.

Output files must be new files with .json, .diff, .patch or .txt extensions. Existing output files are never overwritten. Choose another name or remove an obsolete artifact yourself.

Write behavior and limits

Whole standalone comment lines are removed. Inline comments are replaced with whitespace that separates neighboring tokens and preserves embedded line terminators. UTF-8, UTF-8 BOM, UTF-16 LE/BE BOM, retained CRLF/LF and file permissions are preserved. The result must parse and retain the same non-comment syntax tree, including punctuation. Ambiguous JavaScript automatic semicolon insertion changes are rejected. This syntax check does not establish that deleting an explanation is useful or preserve every external tool’s interpretation of unknown comment directives.

Every edited file is validated and staged before writing. Files changed after selection, symlink paths, hard-linked files and read-only files are rejected. Ordinary commit failures attempt to restore earlier writes and report any rollback failure. Multi-file application is not crash-atomic; avoid concurrent writers while applying. Use source control to revert an applied cleanup.

Diffs display decoded text. Use --apply or plan replay to preserve BOM and UTF-16 encoding; external patch tools are not an encoding-preserving substitute.

Codebase report integration

Enable the advisory rule to include comment review hints in the regular Codebase report:

reforge analyze . --analysis codebase \
  --set "rules.enable=['reforge.codebase.comment_hygiene']"

Or add reforge.codebase.comment_hygiene to [rules].enable in reforge.toml. It is a preview, default-off rule for Rust, JavaScript and TypeScript/TSX. Evidence includes the comment location and hint; protected comments do not produce hints. It belongs to the documentation-integrity family and uses the shared parsed workspace sources. Dataflow-only execution does not run it. The rule cannot be enforced as policy while it is preview. Analysis never modifies source files.