Repository navigation
Expand file tree
/
Copy pathct-search.json
More file actions
146 lines (146 loc) · 7.87 KB
/
Copy pathct-search.json
File metadata and controls
146 lines (146 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
{
"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|auto states the interpretation for every pattern in the invocation (auto is the promotion rule, requested out loud). --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). --detail prints each hit as path:line:text (grep -n); adding --context N (-C) surrounds each hit with N lines shown as path-line-text, so the two rows stay distinguishable and the output can be filtered back down to the hits. 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 / stdin: / text:VALUE payloads; a multi-line payload matches as a line-anchored literal block."
},
"mode": {
"type": "string",
"enum": [
"literal",
"glob",
"regex",
"auto"
],
"description": "How patterns are interpreted. literal|glob|regex pin one reading for every pattern in the invocation; auto states the substring->glob->regex promotion rule out loud. Use literal for verbatim code anchors."
},
"okf-type": {
"type": "string",
"description": "OKF: keep only Markdown concepts whose frontmatter `type` matches this pattern (substring->glob->regex promoted, also pinned by --mode)."
},
"okf-tag": {
"type": "array",
"items": {
"type": "string"
},
"description": "OKF: keep only Markdown concepts whose frontmatter carries all of these tags (repeated or comma-joined)."
},
"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."
},
"context": {
"type": "integer",
"description": "Lines of context printed around each --grep hit, grep's -C: a hit row is path:line:text, a context row is path-line-text, and '--' separates non-adjacent windows across the whole run. Implies --detail; a matched multi-line block shows whole, with the context around it."
},
"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."
},
"json": {
"type": "boolean",
"description": "Emit a structured JSON result {tool, verdict, base, count, lines, matches:[paths]} instead of text; overrides the output mode and --emit."
},
"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."
},
"no-ignore": {
"type": "boolean",
"description": "Walk gitignored / .ignore files too (the .git directory is always skipped); by default the walk skips what git would."
},
"json-pretty": {
"type": "boolean",
"description": "Like --json, but pretty-printed (indented)."
}
},
"required": []
},
"examples": [
{"cmd": "ct search --grep 'TODO|FIXME' --name '*.rs' --base src", "why": "Find every TODO/FIXME in Rust sources under src/ in one call, instead of grep -rn -E 'TODO|FIXME' --include='*.rs' src."},
{"cmd": "ct search --name '*.rs' --type f --base src --list", "why": "List Rust file paths under src/, instead of find src -name '*.rs' -type f."},
{"cmd": "ct search --base src --grep 'fn resolve' --detail --context 3", "why": "Read the matching lines with three lines of context around each - the grep -n -C3 shape, without leaving the suite."},
{"cmd": "ct search --grep 'panic!' --name '*.rs' --quiet --expect none", "why": "Assert there are no panic! calls as a pass/fail gate (exit 1 if any exist), with no piping into wc or grep."}
]
}