qurtail 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mattie Casper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
qurtail-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: qurtail
3
+ Version: 1.0.0
4
+ Summary: Follow logs while compacting conservative repeated patterns
5
+ Author: Mattie Casper
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/Mattie/qurtail
8
+ Project-URL: Issues, https://github.com/Mattie/qurtail/issues
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE.md
12
+ Dynamic: license-file
13
+
14
+ # qurtail can Quell Unwanted Repetition
15
+
16
+ Long-running logs have a bad habit of saying the same thing thousands of times with a new
17
+ timestamp attached. That is tolerable when you're watching a terminal. It gets expensive and
18
+ fairly useless when a coding agent has to read the whole thing.
19
+
20
+ `qurtail` gives you or your agent a smaller view of the stream. It prints the first example of a repeated pattern, shows dots while more copies arrive, and closes the run with an exact count. Warnings, errors, status changes, unfamiliar numbers, and multiline diagnostics stay visible.
21
+
22
+ ```text
23
+ > qurtail -F -n 50 app.log
24
+ 2026-08-08T12:00:00Z INFO refreshed cache request_id=715a
25
+ ........ [8 similar in 1s]
26
+ 2026-08-08T12:00:09Z ERROR cache refresh failed: connection refused
27
+ ..... [5 similar before stop]
28
+ ```
29
+
30
+ A silent monitor is hard to distinguish from a stuck one. Qurtail provides the dots by default as a small sign of life, but you can change that with `--dot-every`.
31
+
32
+ ## Install it
33
+
34
+ Qurtail requires Python 3.11 or newer. It has no runtime dependencies.
35
+
36
+
37
+ To install from PyPI:
38
+ ```bash
39
+ uv tool install qurtail
40
+ # or
41
+ pipx install qurtail
42
+ ```
43
+
44
+ To install from GitHub:
45
+ ```bash
46
+ git clone https://github.com/Mattie/qurtail.git
47
+ cd qurtail
48
+ uv tool install .
49
+ ```
50
+
51
+ Or use `pipx` after cloning:
52
+
53
+ ```bash
54
+ pipx install .
55
+ ```
56
+
57
+ To run the repository once without installing it:
58
+
59
+ ```bash
60
+ uvx --from . qurtail -F -n 50 app.log
61
+ ```
62
+
63
+ ## Follow along!
64
+
65
+ ```bash
66
+ qurtail -F -n 50 app.log
67
+ ```
68
+
69
+ `-n` is the number of existing lines to read when the file opens. The default is 10, like `tail`.
70
+ Both `-f` and `-F` continue following when the file is truncated, replaced, or rotated.
71
+
72
+ Leave off the follow flag when you want to compact a file once and exit:
73
+
74
+ ```bash
75
+ qurtail app.log
76
+ ```
77
+
78
+ For a particularly busy log, print one dot for every ten suppressed records:
79
+
80
+ ```bash
81
+ qurtail -F --dot-every 10 app.log
82
+ ```
83
+
84
+ Every suppressed record produces one dot by default. Qurtail buffers those dots into short runs
85
+ before writing them, then closes the run with the exact repeat count and a newline when the pattern
86
+ changes, 30 seconds pass, or monitoring stops. It doesn't redraw old terminal lines with
87
+ backspaces or carriage returns, so captured output stays readable too.
88
+
89
+ ## Run a command
90
+
91
+ If qurtail is launching the noisy command, use `run`:
92
+
93
+ ```bash
94
+ qurtail run -- pytest -q
95
+ ```
96
+
97
+ Everything after `--` is passed directly to the child command. There is no implicit shell in the
98
+ middle interpreting pipes, substitutions, or redirects.
99
+
100
+ Standard output and standard error are combined and sent through the same conservative reducer.
101
+ Qurtail returns the child's success or failure status. If you interrupt qurtail, it interrupts and
102
+ reaps the child process before exiting. A failed test run should still look like a failed test run;
103
+ saving screen space is no excuse for losing the exit code.
104
+
105
+ The same form works for container logs:
106
+
107
+ ```bash
108
+ qurtail run -- docker logs -f api
109
+ ```
110
+
111
+ ```bash
112
+ qurtail run -- kubectl logs -f deploy/api --timestamps
113
+ ```
114
+
115
+ When another command already owns the pipeline, qurtail can read standard input:
116
+
117
+ ```bash
118
+ producer 2>&1 | qurtail
119
+ ```
120
+
121
+ With no filename and no `run` subcommand, it reads until standard input closes.
122
+
123
+ Run `qurtail -h` for the complete command reference.
124
+
125
+ ## What counts as repetition?
126
+
127
+ Qurtail uses bounded per-stream state to index patterns it has already printed. It recognizes a
128
+ small, corpus-proven set of values that commonly change without changing the meaning of a log
129
+ line:
130
+
131
+ - timestamps
132
+ - UUIDs
133
+ - request, trace, and span IDs
134
+ - standard JSON log metadata
135
+ - stable container and service prefixes
136
+
137
+ The matcher errs on the side of printing a line. It doesn't use a broad fuzzy-similarity score,
138
+ since that is a good way to make an important number disappear. These two lines are different and
139
+ both remain visible:
140
+
141
+ ```text
142
+ replication lag is 1 second
143
+ replication lag is 900 seconds
144
+ ```
145
+
146
+ Unknown shapes, ambiguous values, and unfamiliar changing values also print in full. The same goes
147
+ for malformed structured records and multiline content qurtail isn't sure how to join.
148
+
149
+ Warning, error, and fatal transitions stay visible, along with HTTP status changes and changed
150
+ structured error payloads. Same-level errors with different details get their own full record.
151
+ Tracebacks, stack traces, and other multiline diagnostic blocks stay together. Repeated identical
152
+ errors may be summarized after one complete example.
153
+
154
+ Every suppressed record increments the count for its visible pattern. Suppressed records don't
155
+ teach the matcher new patterns, so a hidden record cannot become the hidden example that makes some
156
+ later line disappear.
157
+
158
+ ### Optional aggressive matching
159
+
160
+ Conservative matching remains the default. When changing values still make repetitive output look
161
+ unique, `--aggressive` also treats these hexadecimal, path, and long-integer values as noise.
162
+
163
+ Keep in mind that sometimes ports, years, durations, byte counts, identifiers, and affected paths can all matter. Only use `--aggressive` when those values are noise.
164
+
165
+ ## Keep the raw output if you'll need it
166
+
167
+ Qurtail is just a viewing helper to reduce noise. You may still want the followed stream captured.
168
+
169
+ When qurtail runs the child command, use `--raw-log` to keep the raw text:
170
+
171
+ ```bash
172
+ qurtail run --raw-log api.raw.log -- docker logs -f api
173
+ ```
174
+
175
+ (The raw-log path must be new. To deliberately replace an existing log, add `--overwrite`.)
176
+
177
+ For a pipe, keep the raw copy before the stream reaches qurtail:
178
+
179
+ ```bash
180
+ docker logs -f api 2>&1 | tee api.raw.log | qurtail
181
+ ```
182
+
183
+ Without `--raw-log`, qurtail doesn't create a transcript or keep a second copy.
184
+
185
+ ## What qurtail doesn't do
186
+
187
+ Qurtail compacts a live local stream while it passes through. It doesn't store logs unless you ask.
188
+
189
+ ## Benchmarks and tests
190
+
191
+ The benchmark suite includes regression fixtures, held-out monitoring episodes, and large-corpus
192
+ runs. Installed-command smoke tests run on Linux, macOS, and Windows.
193
+
194
+ See [`benchmarks/README.md`](benchmarks/README.md) for more. If you have good log data you want to share, please open an issue or pull request. The more diverse the corpus, the better qurtail can be updated to recognize repetition.
195
+
196
+ ## Agent skill
197
+
198
+ The included `qurtail-fluency` skill makes qurtail the default for verbose tests, builds,
199
+ installers, development servers, services, container and Kubernetes workloads, and followed logs.
200
+
201
+ ## Changelog
202
+
203
+ ### 1.0.0
204
+
205
+ - Added opt-in aggressive matching for long integers, prefixed hexadecimal values, and absolute
206
+ paths.
207
+ - Protected existing raw transcripts by default and added an explicit overwrite option.
208
+ - Kept corpus-integrity verification byte-exact across Linux, macOS, and Windows.
209
+ - Included the complete MIT license in source and built distributions.
210
+
211
+ ## License
212
+
213
+ [MIT License](LICENSE.md)
@@ -0,0 +1,200 @@
1
+ # qurtail can Quell Unwanted Repetition
2
+
3
+ Long-running logs have a bad habit of saying the same thing thousands of times with a new
4
+ timestamp attached. That is tolerable when you're watching a terminal. It gets expensive and
5
+ fairly useless when a coding agent has to read the whole thing.
6
+
7
+ `qurtail` gives you or your agent a smaller view of the stream. It prints the first example of a repeated pattern, shows dots while more copies arrive, and closes the run with an exact count. Warnings, errors, status changes, unfamiliar numbers, and multiline diagnostics stay visible.
8
+
9
+ ```text
10
+ > qurtail -F -n 50 app.log
11
+ 2026-08-08T12:00:00Z INFO refreshed cache request_id=715a
12
+ ........ [8 similar in 1s]
13
+ 2026-08-08T12:00:09Z ERROR cache refresh failed: connection refused
14
+ ..... [5 similar before stop]
15
+ ```
16
+
17
+ A silent monitor is hard to distinguish from a stuck one. Qurtail provides the dots by default as a small sign of life, but you can change that with `--dot-every`.
18
+
19
+ ## Install it
20
+
21
+ Qurtail requires Python 3.11 or newer. It has no runtime dependencies.
22
+
23
+
24
+ To install from PyPI:
25
+ ```bash
26
+ uv tool install qurtail
27
+ # or
28
+ pipx install qurtail
29
+ ```
30
+
31
+ To install from GitHub:
32
+ ```bash
33
+ git clone https://github.com/Mattie/qurtail.git
34
+ cd qurtail
35
+ uv tool install .
36
+ ```
37
+
38
+ Or use `pipx` after cloning:
39
+
40
+ ```bash
41
+ pipx install .
42
+ ```
43
+
44
+ To run the repository once without installing it:
45
+
46
+ ```bash
47
+ uvx --from . qurtail -F -n 50 app.log
48
+ ```
49
+
50
+ ## Follow along!
51
+
52
+ ```bash
53
+ qurtail -F -n 50 app.log
54
+ ```
55
+
56
+ `-n` is the number of existing lines to read when the file opens. The default is 10, like `tail`.
57
+ Both `-f` and `-F` continue following when the file is truncated, replaced, or rotated.
58
+
59
+ Leave off the follow flag when you want to compact a file once and exit:
60
+
61
+ ```bash
62
+ qurtail app.log
63
+ ```
64
+
65
+ For a particularly busy log, print one dot for every ten suppressed records:
66
+
67
+ ```bash
68
+ qurtail -F --dot-every 10 app.log
69
+ ```
70
+
71
+ Every suppressed record produces one dot by default. Qurtail buffers those dots into short runs
72
+ before writing them, then closes the run with the exact repeat count and a newline when the pattern
73
+ changes, 30 seconds pass, or monitoring stops. It doesn't redraw old terminal lines with
74
+ backspaces or carriage returns, so captured output stays readable too.
75
+
76
+ ## Run a command
77
+
78
+ If qurtail is launching the noisy command, use `run`:
79
+
80
+ ```bash
81
+ qurtail run -- pytest -q
82
+ ```
83
+
84
+ Everything after `--` is passed directly to the child command. There is no implicit shell in the
85
+ middle interpreting pipes, substitutions, or redirects.
86
+
87
+ Standard output and standard error are combined and sent through the same conservative reducer.
88
+ Qurtail returns the child's success or failure status. If you interrupt qurtail, it interrupts and
89
+ reaps the child process before exiting. A failed test run should still look like a failed test run;
90
+ saving screen space is no excuse for losing the exit code.
91
+
92
+ The same form works for container logs:
93
+
94
+ ```bash
95
+ qurtail run -- docker logs -f api
96
+ ```
97
+
98
+ ```bash
99
+ qurtail run -- kubectl logs -f deploy/api --timestamps
100
+ ```
101
+
102
+ When another command already owns the pipeline, qurtail can read standard input:
103
+
104
+ ```bash
105
+ producer 2>&1 | qurtail
106
+ ```
107
+
108
+ With no filename and no `run` subcommand, it reads until standard input closes.
109
+
110
+ Run `qurtail -h` for the complete command reference.
111
+
112
+ ## What counts as repetition?
113
+
114
+ Qurtail uses bounded per-stream state to index patterns it has already printed. It recognizes a
115
+ small, corpus-proven set of values that commonly change without changing the meaning of a log
116
+ line:
117
+
118
+ - timestamps
119
+ - UUIDs
120
+ - request, trace, and span IDs
121
+ - standard JSON log metadata
122
+ - stable container and service prefixes
123
+
124
+ The matcher errs on the side of printing a line. It doesn't use a broad fuzzy-similarity score,
125
+ since that is a good way to make an important number disappear. These two lines are different and
126
+ both remain visible:
127
+
128
+ ```text
129
+ replication lag is 1 second
130
+ replication lag is 900 seconds
131
+ ```
132
+
133
+ Unknown shapes, ambiguous values, and unfamiliar changing values also print in full. The same goes
134
+ for malformed structured records and multiline content qurtail isn't sure how to join.
135
+
136
+ Warning, error, and fatal transitions stay visible, along with HTTP status changes and changed
137
+ structured error payloads. Same-level errors with different details get their own full record.
138
+ Tracebacks, stack traces, and other multiline diagnostic blocks stay together. Repeated identical
139
+ errors may be summarized after one complete example.
140
+
141
+ Every suppressed record increments the count for its visible pattern. Suppressed records don't
142
+ teach the matcher new patterns, so a hidden record cannot become the hidden example that makes some
143
+ later line disappear.
144
+
145
+ ### Optional aggressive matching
146
+
147
+ Conservative matching remains the default. When changing values still make repetitive output look
148
+ unique, `--aggressive` also treats these hexadecimal, path, and long-integer values as noise.
149
+
150
+ Keep in mind that sometimes ports, years, durations, byte counts, identifiers, and affected paths can all matter. Only use `--aggressive` when those values are noise.
151
+
152
+ ## Keep the raw output if you'll need it
153
+
154
+ Qurtail is just a viewing helper to reduce noise. You may still want the followed stream captured.
155
+
156
+ When qurtail runs the child command, use `--raw-log` to keep the raw text:
157
+
158
+ ```bash
159
+ qurtail run --raw-log api.raw.log -- docker logs -f api
160
+ ```
161
+
162
+ (The raw-log path must be new. To deliberately replace an existing log, add `--overwrite`.)
163
+
164
+ For a pipe, keep the raw copy before the stream reaches qurtail:
165
+
166
+ ```bash
167
+ docker logs -f api 2>&1 | tee api.raw.log | qurtail
168
+ ```
169
+
170
+ Without `--raw-log`, qurtail doesn't create a transcript or keep a second copy.
171
+
172
+ ## What qurtail doesn't do
173
+
174
+ Qurtail compacts a live local stream while it passes through. It doesn't store logs unless you ask.
175
+
176
+ ## Benchmarks and tests
177
+
178
+ The benchmark suite includes regression fixtures, held-out monitoring episodes, and large-corpus
179
+ runs. Installed-command smoke tests run on Linux, macOS, and Windows.
180
+
181
+ See [`benchmarks/README.md`](benchmarks/README.md) for more. If you have good log data you want to share, please open an issue or pull request. The more diverse the corpus, the better qurtail can be updated to recognize repetition.
182
+
183
+ ## Agent skill
184
+
185
+ The included `qurtail-fluency` skill makes qurtail the default for verbose tests, builds,
186
+ installers, development servers, services, container and Kubernetes workloads, and followed logs.
187
+
188
+ ## Changelog
189
+
190
+ ### 1.0.0
191
+
192
+ - Added opt-in aggressive matching for long integers, prefixed hexadecimal values, and absolute
193
+ paths.
194
+ - Protected existing raw transcripts by default and added an explicit overwrite option.
195
+ - Kept corpus-integrity verification byte-exact across Linux, macOS, and Windows.
196
+ - Included the complete MIT license in source and built distributions.
197
+
198
+ ## License
199
+
200
+ [MIT License](LICENSE.md)
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qurtail"
7
+ version = "1.0.0"
8
+ description = "Follow logs while compacting conservative repeated patterns"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE.md"]
13
+ authors = [
14
+ { name = "Mattie Casper" },
15
+ ]
16
+
17
+ [project.urls]
18
+ Repository = "https://github.com/Mattie/qurtail"
19
+ Issues = "https://github.com/Mattie/qurtail/issues"
20
+
21
+ [project.scripts]
22
+ qurtail = "qurtail:main"
23
+
24
+ [tool.setuptools]
25
+ py-modules = ["qurtail"]
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: qurtail
3
+ Version: 1.0.0
4
+ Summary: Follow logs while compacting conservative repeated patterns
5
+ Author: Mattie Casper
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/Mattie/qurtail
8
+ Project-URL: Issues, https://github.com/Mattie/qurtail/issues
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE.md
12
+ Dynamic: license-file
13
+
14
+ # qurtail can Quell Unwanted Repetition
15
+
16
+ Long-running logs have a bad habit of saying the same thing thousands of times with a new
17
+ timestamp attached. That is tolerable when you're watching a terminal. It gets expensive and
18
+ fairly useless when a coding agent has to read the whole thing.
19
+
20
+ `qurtail` gives you or your agent a smaller view of the stream. It prints the first example of a repeated pattern, shows dots while more copies arrive, and closes the run with an exact count. Warnings, errors, status changes, unfamiliar numbers, and multiline diagnostics stay visible.
21
+
22
+ ```text
23
+ > qurtail -F -n 50 app.log
24
+ 2026-08-08T12:00:00Z INFO refreshed cache request_id=715a
25
+ ........ [8 similar in 1s]
26
+ 2026-08-08T12:00:09Z ERROR cache refresh failed: connection refused
27
+ ..... [5 similar before stop]
28
+ ```
29
+
30
+ A silent monitor is hard to distinguish from a stuck one. Qurtail provides the dots by default as a small sign of life, but you can change that with `--dot-every`.
31
+
32
+ ## Install it
33
+
34
+ Qurtail requires Python 3.11 or newer. It has no runtime dependencies.
35
+
36
+
37
+ To install from PyPI:
38
+ ```bash
39
+ uv tool install qurtail
40
+ # or
41
+ pipx install qurtail
42
+ ```
43
+
44
+ To install from GitHub:
45
+ ```bash
46
+ git clone https://github.com/Mattie/qurtail.git
47
+ cd qurtail
48
+ uv tool install .
49
+ ```
50
+
51
+ Or use `pipx` after cloning:
52
+
53
+ ```bash
54
+ pipx install .
55
+ ```
56
+
57
+ To run the repository once without installing it:
58
+
59
+ ```bash
60
+ uvx --from . qurtail -F -n 50 app.log
61
+ ```
62
+
63
+ ## Follow along!
64
+
65
+ ```bash
66
+ qurtail -F -n 50 app.log
67
+ ```
68
+
69
+ `-n` is the number of existing lines to read when the file opens. The default is 10, like `tail`.
70
+ Both `-f` and `-F` continue following when the file is truncated, replaced, or rotated.
71
+
72
+ Leave off the follow flag when you want to compact a file once and exit:
73
+
74
+ ```bash
75
+ qurtail app.log
76
+ ```
77
+
78
+ For a particularly busy log, print one dot for every ten suppressed records:
79
+
80
+ ```bash
81
+ qurtail -F --dot-every 10 app.log
82
+ ```
83
+
84
+ Every suppressed record produces one dot by default. Qurtail buffers those dots into short runs
85
+ before writing them, then closes the run with the exact repeat count and a newline when the pattern
86
+ changes, 30 seconds pass, or monitoring stops. It doesn't redraw old terminal lines with
87
+ backspaces or carriage returns, so captured output stays readable too.
88
+
89
+ ## Run a command
90
+
91
+ If qurtail is launching the noisy command, use `run`:
92
+
93
+ ```bash
94
+ qurtail run -- pytest -q
95
+ ```
96
+
97
+ Everything after `--` is passed directly to the child command. There is no implicit shell in the
98
+ middle interpreting pipes, substitutions, or redirects.
99
+
100
+ Standard output and standard error are combined and sent through the same conservative reducer.
101
+ Qurtail returns the child's success or failure status. If you interrupt qurtail, it interrupts and
102
+ reaps the child process before exiting. A failed test run should still look like a failed test run;
103
+ saving screen space is no excuse for losing the exit code.
104
+
105
+ The same form works for container logs:
106
+
107
+ ```bash
108
+ qurtail run -- docker logs -f api
109
+ ```
110
+
111
+ ```bash
112
+ qurtail run -- kubectl logs -f deploy/api --timestamps
113
+ ```
114
+
115
+ When another command already owns the pipeline, qurtail can read standard input:
116
+
117
+ ```bash
118
+ producer 2>&1 | qurtail
119
+ ```
120
+
121
+ With no filename and no `run` subcommand, it reads until standard input closes.
122
+
123
+ Run `qurtail -h` for the complete command reference.
124
+
125
+ ## What counts as repetition?
126
+
127
+ Qurtail uses bounded per-stream state to index patterns it has already printed. It recognizes a
128
+ small, corpus-proven set of values that commonly change without changing the meaning of a log
129
+ line:
130
+
131
+ - timestamps
132
+ - UUIDs
133
+ - request, trace, and span IDs
134
+ - standard JSON log metadata
135
+ - stable container and service prefixes
136
+
137
+ The matcher errs on the side of printing a line. It doesn't use a broad fuzzy-similarity score,
138
+ since that is a good way to make an important number disappear. These two lines are different and
139
+ both remain visible:
140
+
141
+ ```text
142
+ replication lag is 1 second
143
+ replication lag is 900 seconds
144
+ ```
145
+
146
+ Unknown shapes, ambiguous values, and unfamiliar changing values also print in full. The same goes
147
+ for malformed structured records and multiline content qurtail isn't sure how to join.
148
+
149
+ Warning, error, and fatal transitions stay visible, along with HTTP status changes and changed
150
+ structured error payloads. Same-level errors with different details get their own full record.
151
+ Tracebacks, stack traces, and other multiline diagnostic blocks stay together. Repeated identical
152
+ errors may be summarized after one complete example.
153
+
154
+ Every suppressed record increments the count for its visible pattern. Suppressed records don't
155
+ teach the matcher new patterns, so a hidden record cannot become the hidden example that makes some
156
+ later line disappear.
157
+
158
+ ### Optional aggressive matching
159
+
160
+ Conservative matching remains the default. When changing values still make repetitive output look
161
+ unique, `--aggressive` also treats these hexadecimal, path, and long-integer values as noise.
162
+
163
+ Keep in mind that sometimes ports, years, durations, byte counts, identifiers, and affected paths can all matter. Only use `--aggressive` when those values are noise.
164
+
165
+ ## Keep the raw output if you'll need it
166
+
167
+ Qurtail is just a viewing helper to reduce noise. You may still want the followed stream captured.
168
+
169
+ When qurtail runs the child command, use `--raw-log` to keep the raw text:
170
+
171
+ ```bash
172
+ qurtail run --raw-log api.raw.log -- docker logs -f api
173
+ ```
174
+
175
+ (The raw-log path must be new. To deliberately replace an existing log, add `--overwrite`.)
176
+
177
+ For a pipe, keep the raw copy before the stream reaches qurtail:
178
+
179
+ ```bash
180
+ docker logs -f api 2>&1 | tee api.raw.log | qurtail
181
+ ```
182
+
183
+ Without `--raw-log`, qurtail doesn't create a transcript or keep a second copy.
184
+
185
+ ## What qurtail doesn't do
186
+
187
+ Qurtail compacts a live local stream while it passes through. It doesn't store logs unless you ask.
188
+
189
+ ## Benchmarks and tests
190
+
191
+ The benchmark suite includes regression fixtures, held-out monitoring episodes, and large-corpus
192
+ runs. Installed-command smoke tests run on Linux, macOS, and Windows.
193
+
194
+ See [`benchmarks/README.md`](benchmarks/README.md) for more. If you have good log data you want to share, please open an issue or pull request. The more diverse the corpus, the better qurtail can be updated to recognize repetition.
195
+
196
+ ## Agent skill
197
+
198
+ The included `qurtail-fluency` skill makes qurtail the default for verbose tests, builds,
199
+ installers, development servers, services, container and Kubernetes workloads, and followed logs.
200
+
201
+ ## Changelog
202
+
203
+ ### 1.0.0
204
+
205
+ - Added opt-in aggressive matching for long integers, prefixed hexadecimal values, and absolute
206
+ paths.
207
+ - Protected existing raw transcripts by default and added an explicit overwrite option.
208
+ - Kept corpus-integrity verification byte-exact across Linux, macOS, and Windows.
209
+ - Included the complete MIT license in source and built distributions.
210
+
211
+ ## License
212
+
213
+ [MIT License](LICENSE.md)
@@ -0,0 +1,15 @@
1
+ LICENSE.md
2
+ README.md
3
+ pyproject.toml
4
+ qurtail.py
5
+ setup.py
6
+ qurtail.egg-info/PKG-INFO
7
+ qurtail.egg-info/SOURCES.txt
8
+ qurtail.egg-info/dependency_links.txt
9
+ qurtail.egg-info/entry_points.txt
10
+ qurtail.egg-info/top_level.txt
11
+ tests/test_benchmarks.py
12
+ tests/test_codex_workloads.py
13
+ tests/test_large_corpus.py
14
+ tests/test_performance.py
15
+ tests/test_qurtail.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ qurtail = qurtail:main
@@ -0,0 +1 @@
1
+ qurtail