Skip to content

Cline/Windsurf/Kilo/Antigravity install skips silently if the project's rules file contains the substring "rtk" — e.g. "RTK Query" in a Redux project #3406

Open

Description

@HetCreep

The project-scoped installers decide "already configured" by substring-searching the rules file for RTK or rtk. Any unrelated occurrence makes the install a no-op that reports success.

Provenance: AI-assisted source audit, human-directed, at v0.44.2 (700bdde). Read from source; rtk init was not executed.

The check

src/hooks/init.rs:1640 (Cline), and identically at :1685 (Windsurf), :1738 (Kilo Code), :1796 (Antigravity):

let existing = fs::read_to_string(&rules_path).unwrap_or_default();
if existing.contains("RTK") || existing.contains("rtk") {
    println!("\nRTK already configured for Cline in this project.\n");
    println!("  Rules: .clinerules (already present)");
}

This is a bare substring test over the whole file.

Why it misfires

RTK is the standard abbreviation for Redux Toolkit, and RTK Query is one of its most-used features. A JavaScript or TypeScript project whose .clinerules says something like:

Prefer RTK Query for data fetching; do not add axios.

will make rtk init --agent cline print "RTK already configured for Cline in this project" and write nothing. rtk is then simply not installed, and the message says the opposite.

Lowercase rtk matches even more broadly — any path, package name or prose containing those three letters in sequence.

The same file has the precise version

For Claude, Cursor and Droid, idempotency is exact rather than fuzzy: hook_already_present (init.rs:1120), and :3676 / :3140, compare the actual hook command — is_claude_hook_command shell-splits and checks three tokens. Only these four project-rules installers use a substring.

Suggested fix (untested)

Search for the block markers the installer itself writes (RTK_BLOCK_START / the exact heading it emits) rather than for the letters rtk. That is what makes the check idempotent rather than merely cautious, and it is already the approach used on the marker-based CLAUDE.md path.

Related, same four installers

These write an rtk block into .clinerules / .windsurfrules / .kilocode/rules/rtk-rules.md / .agents/rules/*.md (init.rs:1660, :1705, :1760, :1817) and no uninstall path exists for any of them — reported separately in the uninstall-dispatch issue. So a block appended into a user-authored, usually-committed rules file cannot be removed by rtk.

Activity

  1. pszymkowiak commented on Aug 4, 2026

    @pszymkowiak
    Collaborator

    wshm · Automated triage by AI

    🔍 Automated Triage

    🐛 Category bug
    🟡 Priority medium
    🎯 Confidence 90%

    Summary

    Cline/Windsurf/Kilo/Antigravity project-rules install idempotency check uses a bare substring search for 'rtk'/'RTK', causing false positives (e.g. 'RTK Query' in a Redux project) that silently skip installation while reporting success; fix by matching the actual block markers as done for Claude/Cursor/Droid.

    This looks like a simple fix that could be auto-resolved. Repo maintainers can use /wshm fix to attempt it.

    📁 Relevant files
    • src/hooks/init.rs

    Triaged automatically by wshm · This is an automated analysis, not a human review.

  2. HetCreep commented on Oct 14, 2026

    @HetCreep
    Author

    Re-checked on v1.0.0 (stable, 2026-10-13): the official release binary plus the v1.0.0 source. Provenance: AI-assisted check, human-directed. "ran" = executed against rtk 1.0.0 with a control; "read" = verified from source only.

    Fixed (read, static): the Antigravity sub-claim is obsolete: it is now a plugin manifest (src/hooks/init/antigravity.rs), not a rules file.

    Still live at v1.0.0: Cline (src/hooks/init/instructions_agents.rs:34), Windsurf (:82) and Kilo (:136) still test existing.contains("RTK") || existing.contains("rtk"), print "already configured" and write nothing, so a project rules file that merely mentions "RTK Query" skips the install. There is also still no uninstall handler for those three rules files (uninstall() at init/mod.rs:1380; see #3404).

    Static read only (I did not run init).

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions