Skip to content

Bare-name operands trigger a recursive **/<name> walk from the cwd — intentional? #186

Description

@ak2k

Raising this as a question rather than a PR, since it's a UX call that's yours to make.

Behavior

In expand_glob_patterns_internal (ck-cli/src/path_utils.rs), any slash-free operand gets a recursive fallback:

let is_simple = !pattern.contains('/') && !pattern.contains('\\');
...
if is_simple {
    // glob "**/{pattern}" from base
}

is_simple gates on "contains no separator" — not on whether the operand is actually a glob. So a bare literal recurses too:

mkdir -p proj/deep/nested && cd proj
echo target > deep/nested/host
ck target host          # matches deep/nested/host via the **/host fallback

This is useful for *.rs. It's more surprising for a literal, and the case I care about is the accidental one: a mis-quoted query (ck --lex bootstrap host provision docs/memories) puts ordinary words in the operand slot, and each slash-free word then drives a full recursive walk of the working tree before the search root is computed. On a large tree — or one containing a cloud-storage mount — that's expensive in a way nothing in the command suggests.

Scope, verified

I checked two things I'd assumed were worse, and they're fine:

  • .ckignore is honored on this path — a vendor/-excluded match is correctly skipped.
  • Directory symlinks are not followed by the glob crate's **.

So this is a cost/least-surprise question, not a safety hole. It also runs before the search root exists, so it isn't bounded by the root-narrowing logic.

Options

  1. Leave as-is — recursion for bare names is intended UX.
  2. Gate the fallback on an actual glob metacharacter (*, ?, [), keeping *.rs recursive while a literal stays literal. One-line change; I have it running locally with tests.
  3. Bound the fallback to the resolved search root, or run it through the same WalkBuilder the search path uses.

Happy to send a PR for whichever you prefer — or none, if (1). Worth noting option 2 is a behavior change with two visible edges: ck query README.md would stop matching a nested docs/README.md (users would need **/README.md), and since mcp_server.rs shares this function, bare-name MCP include_patterns would become literal too.

(Related: #184, a different over-broad-traversal path in find_search_root. Independent of this one.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions