Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/filters/gradle.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[filters.gradle]
description = "Compact Gradle build output — strip progress, keep tasks and errors"
match_command = "^(gradle|gradlew|\\./)gradlew?\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^> Configuring project",
"^> Resolving dependencies",
"^> Transform ",
"^Download(ing)?\\s+http",
"^\\s*<-+>\\s*$",
"^> Task :.*UP-TO-DATE$",
"^> Task :.*NO-SOURCE$",
"^> Task :.*FROM-CACHE$",
"^Starting a Gradle Daemon",
"^Daemon will be stopped",
]
truncate_lines_at = 150
max_lines = 50
on_empty = "gradle: ok"

[[tests.gradle]]
name = "strips UP-TO-DATE tasks, keeps build result"
input = "> Configuring project :app\n> Task :app:compileJava UP-TO-DATE\n> Task :app:compileKotlin UP-TO-DATE\n> Task :app:test\n\n3 tests completed, 1 failed\n\nBUILD FAILED in 12s"
expected = "> Task :app:test\n3 tests completed, 1 failed\nBUILD FAILED in 12s"

[[tests.gradle]]
name = "clean build preserved"
input = "BUILD SUCCESSFUL in 8s\n7 actionable tasks: 7 executed"
expected = "BUILD SUCCESSFUL in 8s\n7 actionable tasks: 7 executed"

[[tests.gradle]]
name = "empty after stripping"
input = "> Configuring project :app\n"
expected = "gradle: ok"
20 changes: 20 additions & 0 deletions src/filters/jira.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[filters.jira]
description = "Compact Jira CLI output — strip verbose metadata, keep essentials"
match_command = "^jira\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^\\s*--",
]
truncate_lines_at = 120
max_lines = 40

[[tests.jira]]
name = "strips blank lines from issue list"
input = "TYPE\tKEY\tSUMMARY\tSTATUS\n\nStory\tPROJ-123\tAdd login feature\tIn Progress\n\nBug\tPROJ-456\tFix crash on startup\tOpen"
expected = "TYPE\tKEY\tSUMMARY\tSTATUS\nStory\tPROJ-123\tAdd login feature\tIn Progress\nBug\tPROJ-456\tFix crash on startup\tOpen"

[[tests.jira]]
name = "single issue view"
input = "KEY: PROJ-123\nSummary: Add login feature\nStatus: In Progress\nAssignee: john@example.com"
expected = "KEY: PROJ-123\nSummary: Add login feature\nStatus: In Progress\nAssignee: john@example.com"
26 changes: 26 additions & 0 deletions src/filters/just.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[filters.just]
description = "Compact just task runner output — strip recipe headers, keep command output"
match_command = "^just\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^\\s*Available recipes:",
"^\\s*just --list",
]
truncate_lines_at = 150
max_lines = 50

[[tests.just]]
name = "preserves command output"
input = "cargo test\n\ntest result: ok. 42 passed; 0 failed\n"
expected = "cargo test\ntest result: ok. 42 passed; 0 failed"

[[tests.just]]
name = "preserves error output"
input = "error: Compilation failed\nsrc/main.rs:10: expected `;`"
expected = "error: Compilation failed\nsrc/main.rs:10: expected `;`"

[[tests.just]]
name = "empty input"
input = ""
expected = ""
30 changes: 30 additions & 0 deletions src/filters/mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[filters.mise]
description = "Compact mise task runner output — strip status lines, keep task results"
match_command = "^mise\\s+(run|exec|install|upgrade)\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^mise\\s+(trust|install|upgrade).*✓",
"^mise\\s+Installing\\s",
"^mise\\s+Downloading\\s",
"^mise\\s+Extracting\\s",
"^mise\\s+\\w+@[\\d.]+ installed",
]
truncate_lines_at = 150
max_lines = 50
on_empty = "mise: ok"

[[tests.mise]]
name = "strips install noise, keeps task output"
input = "mise Installing node@20.0.0\nmise Downloading node@20.0.0\nmise Extracting node@20.0.0\nmise node@20.0.0 installed\n\nlint check passed\n2 warnings found"
expected = "lint check passed\n2 warnings found"

[[tests.mise]]
name = "preserves error output"
input = "mise run lint\nError: biome check failed\nsrc/index.ts:5 — unused variable"
expected = "mise run lint\nError: biome check failed\nsrc/index.ts:5 — unused variable"

[[tests.mise]]
name = "empty after stripping"
input = "mise trust ~/dev/.mise.toml ✓\nmise install node@20 ✓\n"
expected = "mise: ok"
25 changes: 25 additions & 0 deletions src/filters/nx.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[filters.nx]
description = "Compact Nx monorepo output — strip task graph noise, keep results"
match_command = "^(pnpm\\s+)?nx\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^\\s*>\\s*NX\\s+Running target",
"^\\s*>\\s*NX\\s+Nx read the output",
"^\\s*>\\s*NX\\s+View logs",
"^———————",
"^—————————",
"^\\s+Nx \\(powered by",
]
truncate_lines_at = 150
max_lines = 60

[[tests.nx]]
name = "strips Nx noise, keeps build output"
input = "\n > NX Running target build for project myapp\n\n———————————————————————————————————————\nCompiled successfully.\nOutput: dist/apps/myapp\n\n > NX View logs at /tmp/.nx/runs/abc123\n\n Nx (powered by computation caching)\n"
expected = "Compiled successfully.\nOutput: dist/apps/myapp"

[[tests.nx]]
name = "preserves error output"
input = "ERROR: Cannot find module '@myapp/shared'\n\n > NX Running target build for project myapp\n\nFailed at step: build"
expected = "ERROR: Cannot find module '@myapp/shared'\nFailed at step: build"
23 changes: 23 additions & 0 deletions src/filters/ollama.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[filters.ollama]
description = "Strip ANSI spinners and cursor control from ollama output, keep final text"
match_command = "^ollama\\s+run\\b"
strip_ansi = true
strip_lines_matching = [
"^[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏\\s]*$",
"^\\s*$",
]

[[tests.ollama]]
name = "strips spinner lines, keeps response"
input = "⠋ \n⠙ \n⠹ \nHello! How can I help you today?"
expected = "Hello! How can I help you today?"

[[tests.ollama]]
name = "preserves multi-line response"
input = "⠋ \n⠙ \nLine one of the response.\nLine two of the response."
expected = "Line one of the response.\nLine two of the response."

[[tests.ollama]]
name = "empty input"
input = ""
expected = ""
28 changes: 28 additions & 0 deletions src/filters/spring-boot.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[filters.spring-boot]
description = "Compact Spring Boot output — strip banner and verbose startup logs, keep key events"
match_command = "^(mvn\\s+spring-boot:run|java\\s+-jar.*\\.jar|gradle\\s+.*bootRun)"
strip_ansi = true
keep_lines_matching = [
"Started\\s.*\\sin\\s",
"Tomcat started on port",
"ERROR",
"WARN",
"Exception",
"Caused by:",
"Application run failed",
"BUILD\\s",
"Tests run:",
"FAILURE",
"listening on port",
]
max_lines = 30

[[tests.spring-boot]]
name = "keeps startup summary and errors"
input = " . ____ _ \n /\\\\ / ___'_ __ _ _(_)_ __ \n( ( )\\___ | '_ | '_| | '_ \\ \n \\/ ___)| |_)| | | | | || )\n ' |____| .__|_| |_|_| |_\\__|\n :: Spring Boot :: (v3.2.0)\n2024-01-01 INFO Initializing Spring\n2024-01-01 INFO Bean 'dataSource' created\n2024-01-01 INFO Tomcat started on port 8080\n2024-01-01 INFO Started MyApp in 3.2 seconds"
expected = "2024-01-01 INFO Tomcat started on port 8080\n2024-01-01 INFO Started MyApp in 3.2 seconds"

[[tests.spring-boot]]
name = "preserves errors"
input = " :: Spring Boot :: (v3.2.0)\n2024-01-01 INFO Initializing Spring\n2024-01-01 ERROR Application run failed\nCaused by: java.lang.NullPointerException"
expected = "2024-01-01 ERROR Application run failed\nCaused by: java.lang.NullPointerException"
27 changes: 27 additions & 0 deletions src/filters/task.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[filters.task]
description = "Compact go-task output — strip task headers, keep command results"
match_command = "^task\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^task: \\[.*\\] ",
"^task: Task .* is up to date",
]
truncate_lines_at = 150
max_lines = 50
on_empty = "task: ok"

[[tests.task]]
name = "strips task headers, keeps output"
input = "task: [build] go build ./...\n\ntask: [test] go test ./...\nok myapp 0.5s\n\ntask: Task \"lint\" is up to date"
expected = "ok myapp 0.5s"

[[tests.task]]
name = "preserves error output"
input = "task: [build] go build ./...\n./main.go:10: undefined: foo\ntask: Failed to run task \"build\": exit status 1"
expected = "./main.go:10: undefined: foo\ntask: Failed to run task \"build\": exit status 1"

[[tests.task]]
name = "all up to date"
input = "task: Task \"build\" is up to date\ntask: Task \"lint\" is up to date\n"
expected = "task: ok"
30 changes: 30 additions & 0 deletions src/filters/turbo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[filters.turbo]
description = "Compact Turborepo output — strip cache status noise, keep task results"
match_command = "^turbo\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^\\s*cache (hit|miss|bypass)",
"^\\s*\\d+ packages in scope",
"^\\s*Tasks:\\s+\\d+",
"^\\s*Duration:\\s+",
"^\\s*Remote caching (enabled|disabled)",
]
truncate_lines_at = 150
max_lines = 50
on_empty = "turbo: ok"

[[tests.turbo]]
name = "strips cache noise, keeps task output"
input = " cache hit, replaying logs abc123\n cache miss, executing abc456\n\n3 packages in scope\n\n> myapp:build\n\nCompiled successfully.\n\nTasks: 2 successful, 2 total (1 cached)\nDuration: 3.2s"
expected = "> myapp:build\nCompiled successfully."

[[tests.turbo]]
name = "preserves error output"
input = "> myapp:lint\n\nError: src/index.ts(5,1): error TS2304\n\nTasks: 0 successful, 1 total\nDuration: 1.1s"
expected = "> myapp:lint\nError: src/index.ts(5,1): error TS2304"

[[tests.turbo]]
name = "empty after stripping"
input = " cache hit, replaying logs abc\n\n"
expected = "turbo: ok"
21 changes: 21 additions & 0 deletions src/filters/yadm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[filters.yadm]
description = "Compact yadm (git wrapper) output — same filtering as git"
match_command = "^yadm\\b"
strip_ansi = true
strip_lines_matching = [
"^\\s*$",
"^\\s*\\(use \"git ",
"^\\s*\\(use \"yadm ",
]
truncate_lines_at = 120
max_lines = 40

[[tests.yadm]]
name = "strips hint lines"
input = "On branch main\nYour branch is up to date with 'origin/main'.\n\n (use \"yadm add\" to update what will be committed)\n\nChanges not staged for commit:\n modified: .bashrc"
expected = "On branch main\nYour branch is up to date with 'origin/main'.\nChanges not staged for commit:\n modified: .bashrc"

[[tests.yadm]]
name = "short output preserved"
input = "Already up to date."
expected = "Already up to date."
10 changes: 5 additions & 5 deletions src/toml_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1610,8 +1610,8 @@ match_command = "^make\\b"
let filters = make_filters(BUILTIN_TOML);
assert_eq!(
filters.len(),
47,
"Expected exactly 47 built-in filters, got {}. \
57,
"Expected exactly 57 built-in filters, got {}. \
Update this count when adding/removing filters in src/filters/.",
filters.len()
);
Expand Down Expand Up @@ -1668,11 +1668,11 @@ expected = "output line 1\noutput line 2"
let combined = format!("{}\n\n{}", BUILTIN_TOML, new_filter);
let filters = make_filters(&combined);

// All 47 existing filters still present + 1 new = 48
// All 57 existing filters still present + 1 new = 58
assert_eq!(
filters.len(),
48,
"Expected 48 filters after concat (47 built-in + 1 new)"
58,
"Expected 58 filters after concat (57 built-in + 1 new)"
);

// New filter is discoverable
Expand Down
Loading