{
"name": "ct-search",
"description": "Recursively find files by name, type, size, and content from a chosen root, replacing find|xargs|grep pipelines. An entry matches only when all supplied predicates hold. A search can also be posed as a pass/fail test: --question frames it, --expect sets an expectation over the match count, and --emit prints a templated verdict. The exit status follows the verdict = --expect applied to the count: 0 SUCCESS, 1 ERROR, 2 usage/runtime error; the default expectation 'any' makes this 0 if anything matched and 1 if not. Pattern arguments use substring->glob->regex promotion: text with no metacharacters is a literal substring; glob metacharacters (* ? [ ]) that are not a valid regex are treated as a glob; otherwise the pattern is used as a regex. --mode literal|glob|regex pins the interpretation (promotion off) for every pattern in the invocation. --grep accepts payload schemes: file:PATH reads the pattern verbatim from a file (literal by default), text:VALUE escapes the prefix; a multi-line pattern matches as a line-anchored literal BLOCK (K lines match K consecutive source lines byte-for-byte; each occurrence counts at its start line; under --detail a block with no match reports its nearest miss to stderr). Invoke as `ct search ...` or `ct-search ...`.",
"input_schema": {
"type": "object",
"properties": {
"base": {
"type": "string",
"description": "Search root, relative or absolute, independent of the current working directory.",
"default": "."
},
"name": {
"type": "string",
"description": "File-name pattern. '|'-separated alternatives, each substring->glob->regex promoted and anchored to the whole name (e.g. '*.java|*.kt')."
},
"type": {
"type": "array",
"items": {
"type": "string",
"enum": [
"f",
"d",
"l"
]
},
"description": "Restrict to entry kinds: f=regular file, d=directory, l=symlink. May be repeated or comma-joined."
},
"grep": {
"type": "string",
"description": "Content pattern, substring->glob->regex promoted and searched unanchored against file contents. Implies regular files. Accepts file:PATH / text:VALUE payloads; a multi-line payload matches as a line-anchored literal block."
},
"mode": {
"type": "string",
"enum": [
"literal",
"glob",
"regex"
],
"description": "Pin how patterns are interpreted; promotion off for every pattern in the invocation. Use literal for verbatim code anchors."
},
"size": {
"type": "string",
"description": "Size predicate [+|-]N[k|m|g]: +N larger than, -N smaller than, N at least N. Applies to regular files."
},
"hidden": {
"type": "boolean",
"description": "Include dot-entries (names starting with '.'). Default: skipped."
},
"follow": {
"type": "boolean",
"description": "Follow symlinks while traversing."
},
"limit": {
"type": "integer",
"description": "Stop after this many matches."
},
"question": {
"type": "string",
"description": "Question this search answers, framing it as a test; printed as a '== ... ==' banner unless quiet."
},
"expect": {
"type": "string",
"description": "Verdict expectation over the match count; default 'any'. One of: any (>=1), none (==0), N (>=N), =N (==N), +N (>N), -N (<N). 'none' inverts a search into a negative assertion that passes when nothing matches."
},
"emit": {
"type": "string",
"description": "Template written to stdout after the search (alias: emit-stdout). Tokens: {RESULT} {QUESTION} {COUNT} {LINES} {BASE} {MATCHES}."
},
"emit-stderr": {
"type": "string",
"description": "Template written to stderr after the search. Same tokens as emit."
},
"list": {
"type": "boolean",
"description": "Output mode: print one matching path per line. This is the default mode."
},
"summary": {
"type": "boolean",
"description": "Output mode: print counts only. Mutually exclusive with the other output modes."
},
"detail": {
"type": "boolean",
"description": "Output mode: print matches plus, for --grep, each hit as path:line:text. Mutually exclusive with the other output modes."
},
"quiet": {
"type": "boolean",
"description": "Output mode: print no per-match output and no --question banner; report via exit status (and --emit, which still fires). Mutually exclusive with the other output modes."
},
"timeout": {
"type": "number",
"description": "Abort with exit 2 (and a one-line message) if the search exceeds SECS seconds (fractional allowed)."
},
"heartbeat": {
"type": "number",
"description": "Print a liveness pulse every SECS seconds (fractional allowed) while the run is in progress."
},
"heartbeat-emit": {
"type": "string",
"description": "Heartbeat line template. Tokens: {ELAPSED} (whole seconds so far) {TOOL}. Default: \"[{ELAPSED}s]\"."
},
"heartbeat-to": {
"type": "string",
"enum": [
"stderr",
"stdout"
],
"description": "Stream heartbeat pulses are written to. Default: stderr."
}
},
"required": []
}
}