Skip to content

feat(fix): auto-fix tools-duplicate by removing duplicate tool entries - #47

Merged
protosphinx merged 1 commit into
mainfrom
bot/fix-tools-duplicate
Jul 27, 2026
Merged

feat(fix): auto-fix tools-duplicate by removing duplicate tool entries#47
protosphinx merged 1 commit into
mainfrom
bot/fix-tools-duplicate

Conversation

@protosphinx

Copy link
Copy Markdown
Member

Why

The tools-duplicate diagnostic fires when an author lists the same tool more than once in allowed-tools: or the legacy tools: field. There is one obvious safe correction: remove the duplicate entries while preserving the order of first occurrence. This PR wires that fix into --fix mode, consistent with the four existing auto-corrections (name-drift, tool-fields-ambiguous, name-whitespace, deprecated-tools-field).

What

  • src/fix.ts: new tools-duplicate branch in applyFixes; three private helpers:
    • rewriteDeduplicateTools: top-level coordinator, extracts the frontmatter block and calls the two specialised rewriters.
    • deduplicateToolsStringLine: handles allowed-tools: (always a string per schema) and the string form of tools: - splits by space/comma (paren-aware), deduplicates, rejoins with the original separator.
    • deduplicateToolsBlockSequence: handles the tools: block-sequence form ( - item lines) by skipping duplicate items.
  • Updated the applyFixes JSDoc to document the new fix.

Tests

Five new cases in test/fix.test.ts under applyFixes - tools-duplicate:

  • Removes duplicate from allowed-tools: (space-separated string)
  • Removes duplicates from tools: block sequence
  • Skips when no textual duplicates present (already clean)
  • Dry-run does not write to disk
  • Notes array contains a human-readable description

All 197 tests pass.

Self-merge gate

  • all CI checks pass
  • LOC delta < 250 (242 lines: 126 added to src/fix.ts, 83 added to test/fix.test.ts, 33 diff headers/context)
  • no public-API surface change (src/index.ts not modified; applyFixes signature unchanged)
  • no runtime-dependency additions
  • no workflow file changes
  • tests added or extended (test/fix.test.ts, 5 new tests)

Generated by Claude Code

Extends the --fix mode to handle the tools-duplicate diagnostic.
Deduplicates allowed-tools: (space- or comma-separated string) and the
legacy tools: field (block sequence or unquoted string), preserving
first-occurrence order in both cases. Quoted string values are left
unchanged since text-level parsing is not safe for them.

Five new tests cover: space-separated allowed-tools, block-sequence
tools, skip when already clean, dry-run, and notes population.
@protosphinx protosphinx added the automated Opened by the daily bot label Jul 27, 2026 — with Claude
@protosphinx
protosphinx merged commit ab020fb into main Jul 27, 2026
3 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3dee26665

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/fix.ts
* YAML line. Quoted values are left unchanged (safe-parse is not feasible).
*/
function deduplicateToolsStringLine(block: string, field: string): string {
const re = new RegExp(`^([ \\t]*${field}[ \\t]*:[ \\t]*)([^\\[\\r\\n].*)$`, "m");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict deduplication to the top-level field

When a valid passthrough extension object contains an indented allowed-tools: key before the real top-level key, this regex matches and rewrites the nested value instead. For example, with settings:\n allowed-tools: Read Read\nallowed-tools: Bash Bash, --fix modifies settings.allowed-tools, reports the diagnostic fixed, and leaves the diagnosed top-level duplicate untouched. Require zero indentation when locating frontmatter tool fields.

Useful? React with 👍 / 👎.

Comment thread src/fix.ts
Comment on lines +247 to +251
// allowed-tools is always a string per schema; handle unquoted inline form.
newBlock = deduplicateToolsStringLine(newBlock, "allowed-tools");
// tools (legacy) may be a block sequence or an unquoted string.
newBlock = deduplicateToolsBlockSequence(newBlock, "tools");
newBlock = deduplicateToolsStringLine(newBlock, "tools");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Deduplicate legacy blocks before renaming them

For an actual CLI run on tools:\n - Read\n - Bash\n - Read, runChecks emits deprecated-tools-field before tools-duplicate, so the earlier fix renames the key to allowed-tools: before this coordinator runs. These lines only process block sequences named tools, causing the newly supported duplicate fix to be skipped in precisely the legacy block-sequence case it claims to handle; deduplicate before the rename or also handle the renamed buffered form.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated Opened by the daily bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant