gcla/termshark
A terminal UI for tshark, inspired by Wireshark
Stale — last commit 2y ago
weakest axislast commit was 2y ago; top contributor handles 97% of recent commits
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓3 active contributors
- ✓MIT licensed
- ✓CI configured
Show all 7 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Small team — 3 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 97% of recent commits
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/gcla/termshark)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/gcla/termshark on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: gcla/termshark
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/gcla/termshark shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 3 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 97% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live gcla/termshark
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/gcla/termshark.
What it runs against: a local clone of gcla/termshark — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in gcla/termshark | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 767 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of gcla/termshark. If you don't
# have one yet, run these first:
#
# git clone https://github.com/gcla/termshark.git
# cd termshark
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of gcla/termshark and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "gcla/termshark(\\.git)?\\b" \\
&& ok "origin remote is gcla/termshark" \\
|| miss "origin remote is not gcla/termshark (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/termshark/termshark.go" \\
&& ok "cmd/termshark/termshark.go" \\
|| miss "missing critical file: cmd/termshark/termshark.go"
test -f "pkg/pcap/loader.go" \\
&& ok "pkg/pcap/loader.go" \\
|| miss "missing critical file: pkg/pcap/loader.go"
test -f "pkg/pdmltree/pdmltree.go" \\
&& ok "pkg/pdmltree/pdmltree.go" \\
|| miss "missing critical file: pkg/pdmltree/pdmltree.go"
test -f "pkg/psmlmodel/model.go" \\
&& ok "pkg/psmlmodel/model.go" \\
|| miss "missing critical file: pkg/psmlmodel/model.go"
test -f "go.mod" \\
&& ok "go.mod" \\
|| miss "missing critical file: go.mod"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 767 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~737d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/gcla/termshark"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Termshark is a terminal UI wrapper around tshark (Wireshark's command-line tool) that brings Wireshark-like packet inspection to the terminal. It reads pcap files or sniffs live network interfaces, applies Wireshark display filters, reassembles TCP/UDP flows, and lets users inspect packet details in a TUI built with tcell and gowid—all compiled to a single statically-linked Go binary. Monorepo structure: cmd/termshark/termshark.go is the entry point; pkg/ contains 13+ domain packages (cli flags, config, packet loading, parsing, formatting); assets/ holds embedded themes (TOML files) and icons via rakyll/statik; configs/profiles/ manages user profiles; the TUI is built entirely on top of github.com/gcla/gowid which wraps tcell.
👥Who it's for
Network engineers, security researchers, and DevOps practitioners debugging network issues on remote machines (especially Linux servers) where running a GUI is impractical or impossible; users who want Wireshark's filtering power without the overhead of X11 forwarding or scp'ing large pcaps back to their desktop.
🌱Maturity & risk
Actively maintained and production-ready. The project reached v2.4 with significant features (packet search, color profiles, column configuration), has CI via GitHub Actions and Travis, and spans 1.2M lines of Go code. Releases are published to GitHub and distributed via multiple package managers (Homebrew, Arch, Debian, etc.), indicating stable maturity.
Relatively low risk: single maintainer (gcla) is a potential concern for long-term sustainability, but the codebase is pure Go with well-vetted dependencies (tcell, gowid, tshark as external subprocess). The dependency on tshark being present in PATH and correct Wireshark version is a runtime constraint. No major breaking changes evident in recent CHANGELOG; Go 1.13+ is the floor.
Active areas of work
The project is in a stable, incremental improvement phase. V2.4 (most recent tag visible) added packet search and profile management. The .github/workflows/go.yml indicates active CI. The repo has defined issue templates for bugs and features, suggesting ongoing maintenance. No major refactors or breaking changes are evident in recent activity.
🚀Get running
git clone https://github.com/gcla/termshark.git
cd termshark
GO111MODULE=on go install ./cmd/termshark
# Add ~/go/bin to PATH
# Ensure tshark is installed (e.g., via 'brew install wireshark' or 'apt install tshark')
termshark -r <pcap_file> # inspect a pcap
termshark -i eth0 icmp # sniff live interface
Daily commands:
go install ./cmd/termshark
termshark -r test.pcap # read pcap
termshark -i eth0 # live capture
termshark -h # see all flags
# Config is auto-created in ~/.config/termshark/ on first run
🗺️Map of the codebase
cmd/termshark/termshark.go— Main entry point that initializes the UI framework, CLI flags, and event loop—every contributor must understand the startup sequencepkg/pcap/loader.go— Core PCAP loading and tshark command orchestration; handles packet capture, filtering, and PDML/PSML parsing—critical for packet data flowpkg/pdmltree/pdmltree.go— Parses and models PDML (packet details markup language) into tree structures used throughout the UI—foundational for packet inspectionpkg/psmlmodel/model.go— Data model for packet summary list (PSML); manages the main packet table view and sorting—backbone of the UI layergo.mod— Declares dependencies on gowid (TUI framework), gdamore/tcell (terminal rendering), and antchfx/xmlquery (PDML parsing)—understand upstream API contractspkg/shark/columnformat.go— Transforms Wireshark column configurations into display formats; bridges native Wireshark config files with termshark's renderingpkg/streams/follow.go— Implements TCP/UDP stream reassembly and follow logic; essential for the conversation and follow-flow features
🛠️How to make changes
Add a new display filter or Wireshark feature
- Add parsing logic in
pkg/fields/fields.goto recognize the new filter syntax and validate it (pkg/fields/fields.go) - Update
pkg/pcap/loader.goto pass the filter to tshark via-Yor appropriate flag (pkg/pcap/loader.go) - If the feature returns new PDML fields, extend the tree model in
pkg/pdmltree/pdmltree.go(pkg/pdmltree/pdmltree.go) - Add UI bindings in
cmd/termshark/termshark.goor create a new gowid widget (cmd/termshark/termshark.go)
Add a new color theme
- Create a new
.tomlfile inassets/themes/following the structure ofdefault-256.toml(assets/themes/default-256.toml) - Define color mappings for all UI elements (packet list, tree, hex pane, status bar, etc.) (
assets/themes/default-256.toml) - Register the theme in
configs/profiles/profiles.goso it appears in the profile selector (configs/profiles/profiles.go) - Test with the CLI flag
--profile=<theme-name>to ensure colors load correctly (pkg/cli/flags.go)
Add a new packet analysis or inspection feature
- Implement parsing logic in a new file under
pkg/<feature>/(e.g.,pkg/analysis/analyzer.go) (pkg/pcap/loader.go) - Hook the feature into
pkg/pcap/loader.goto run after tshark data is loaded (pkg/pcap/loader.go) - Create or extend a model in
pkg/psmlmodel/model.goto store results if they affect the packet table (pkg/psmlmodel/model.go) - Create a new gowid widget or view in
cmd/termshark/termshark.goand wire it to the main layout (cmd/termshark/termshark.go)
Add support for a new stream or conversation analysis
- Extend stream parsing in
pkg/streams/follow.goorpkg/streams/parse.goto recognize the new flow type (pkg/streams/follow.go) - Update
pkg/streams/loader.goto extract the new stream type from capture data (pkg/streams/loader.go) - If analyzing conversations, extend
pkg/convs/loader.goandpkg/convs/types.go(pkg/convs/loader.go) - Wire the results into the UI in
cmd/termshark/termshark.go(cmd/termshark/termshark.go)
🔧Why these technologies
- gowid (TUI framework) — Provides high-level terminal UI widget abstraction (lists, trees, panes) for building complex layouts without raw tcell
- gdamore/tcell — Cross-platform terminal rendering engine; abstracts differences between Linux, macOS, Windows, and Android termux
- tshark (subprocess) — Leverages Wireshark's mature packet dissection engine; avoids reimplementing protocol parsers
- antchfx/xmlquery (XPath) — Efficient PDML XML parsing and field extraction via XPath; avoids full DOM marshaling
- Go + single binary — Compiles to standalone executables for all platforms; simplifies distribution and installation
⚖️Trade-offs already made
- Subprocess tshark vs. native packet library (libpcap/
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
- tshark must be in PATH: The app spawns tshark as a subprocess; if it's not in PATH or the wrong version is installed, silent failures occur. 2.
GO111MODULE=onrequired for Go <1.16: Explicit module mode is needed for older Go versions. 3. Theme rebuild: Changing.tomlfiles inassets/themes/requires runninggo generate ./assetsand rebuilding the binary. 4. Config directory platform-specific: Usesshibukawa/configdirwhich resolves to different paths on Linux (~/.config), macOS (~/Library/Application Support), Windows (%APPDATA%). 5. XML parsing from tshark: If tshark output format changes,pkg/fields/fields.goXPath queries may break silently; no schema validation.
🏗️Architecture
💡Concepts to learn
- Packet dissection (OSI layers) — Termshark displays packet headers broken down by protocol layer (Ethernet → IP → TCP/UDP → application); understanding the OSI model and how tshark parses nested headers is fundamental to interpreting the UI.
- Display filters (Wireshark syntax) — Users filter packets using Wireshark's domain-specific filter language (e.g.,
tcp.port == 443); termshark passes these directly to tshark, so understanding filter semantics is crucial for feature development. - TCP/UDP flow reassembly — Termshark's 'Conversations' view reassembles packets by protocol and endpoint;
pkg/convs/loader.gouses tshark's reassembly engine to reconstruct bidirectional flows. - Terminal capability detection (terminfo) — Termshark ships multiple color themes (8-color, 16-color, 256-color) because not all terminals support the same palette; tcell auto-detects capabilities and gowid/termshark select the appropriate theme.
- Subprocess I/O streaming & JSON parsing — Termshark spawns tshark as a long-lived subprocess and reads its JSON/XML output line-by-line in real-time; efficient streaming and incremental parsing are critical for large pcaps.
- Embedded static assets (statik) — Color themes and other resources are baked into the binary via rakyll/statik so the executable is truly standalone; understanding
go generateand the statik workflow is needed to add new themes. - Configuration hot-reloading with fsnotify — Termshark watches for changes to the config file on disk and reloads themes/profiles without restarting;
pkg/confwatcher/uses fsnotify to detect file changes and signal the UI.
🔗Related repos
wireshark/wireshark— The upstream project that provides tshark; understanding Wireshark's dissector plugins and filter syntax is essential contextgcla/gowid— Termshark's core TUI framework; a Go wrapper around tcell that handles widget composition, layout, and event routinggdamore/tcell— The underlying terminal cell-based rendering library; understanding tcell primitives helps optimize TUI performancespf13/viper— Configuration management library used by termshark for reading TOML/JSON config files and environment variablessirupsen/logrus— Logging framework used throughout termshark; understanding its structured logging helps debug packet parsing issues
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for pkg/pcap/pdml.go and pkg/pcap/loader.go
The PDML parsing logic is critical to termshark's core functionality (converting tshark XML output to displayable packet data), but currently only has loader_tshark_test.go. The pdml.go file likely contains complex parsing logic that deserves dedicated test coverage with edge cases (malformed XML, missing fields, nested protocol structures). This reduces bugs in packet display and filtering.
- [ ] Create pkg/pcap/pdml_test.go with tests for PDML unmarshaling functions
- [ ] Add test cases for edge cases: empty packets, deeply nested protocols, missing attributes
- [ ] Verify test data in pkg/pcap/testdata/ covers various packet types and add missing ones
- [ ] Ensure >80% code coverage for pdml.go using 'go test -cover'
Add GitHub Actions workflow for cross-platform binary builds and releases
The repo has .goreleaser.yml configured but relies on .travis.yml (outdated). GitHub Actions is native to the platform and .github/workflows/go.yml exists but likely doesn't handle releases. A proper release workflow would automatically build and publish binaries for Linux, macOS, BSD, Windows, and Android (termux) on git tags, reducing manual maintainer burden and improving release consistency.
- [ ] Create .github/workflows/release.yml triggered on git tag creation
- [ ] Configure goreleaser step to build binaries for all supported platforms (linux/amd64, darwin/amd64, darwin/arm64, windows, bsd variants)
- [ ] Add step to publish releases to GitHub Releases with checksums
- [ ] Test workflow by creating a release tag and verifying artifacts appear
Add integration tests for pkg/pcap/cmds.go tshark command execution
The cmds.go and cmds_unix.go/cmds_windows.go files handle critical tshark subprocess communication and platform-specific behavior, but there's no dedicated test coverage. Adding integration tests would catch regressions in filter syntax, capture options, and cross-platform command generation before they affect users in the field.
- [ ] Create pkg/pcap/cmds_test.go with tests for command building functions
- [ ] Add tests for various display filters, capture options, and interface specifications
- [ ] Create platform-specific tests: cmds_unix_test.go and cmds_windows_test.go for sudo/permission handling
- [ ] Use testdata/*.pcap files to verify actual tshark execution when available
🌿Good first issues
- Add unit tests for pkg/format/hexdump.go and pkg/format/printable.go: Both files exist but
hexdump_test.gois already present whileprintable.gohas no corresponding test. A new contributor could write tests for the printable formatter to improve code coverage and learn the data formatting pipeline. - Document the config file format in docs/UserGuide.md:
configs/termshark-dd01307f2423.json.encis an encrypted example, but the guide doesn't explain the unencrypted JSON schema (fields, nesting, types). A new contributor could reverse-engineer the config structure frompkg/confwatcher/and document it. - Add Windows-specific tests for pkg/cli/flags_windows.go: A separate
flags_windows.goexists but likely has no cross-platform test coverage. A contributor with Windows access (or using a VM) could add tests for Windows-specific flag behavior.
⭐Top contributors
Click to expand
Top contributors
📝Recent commits
Click to expand
Recent commits
e8a1ec6— Changelog updates for latest merges (gcla)230d393— Thanks @uzxmx for the hex view navigation improvements (gcla)24ace37— Fix a broken test (gcla)172587e— Merge remote-tracking branch 'uzxmx/master' (gcla)1569032— Update CI for Go 1.19 (gcla)65dd428— Use latest gowid for terminal optimizations (gcla)974965f— Map 'gg'/'G' to move to the first/last row for hexview (uzxmx)024bcb4— Fix: move to the last pos when out of the upper bound (uzxmx)6e2290e— Push updated README for contributors (gcla)8f4cedf— Thanks to @luzpaz for fixing all the typos (gcla)
🔒Security observations
- High · Encrypted Configuration File in Repository —
configs/termshark-dd01307f2423.json.enc. File 'configs/termshark-dd01307f2423.json.enc' appears to be an encrypted configuration file stored in version control. While encrypted, the presence of this file suggests sensitive data handling. If the encryption key is compromised or stored insecurely, this could expose configuration secrets. Fix: Remove encrypted config files from version control. Use environment variables or secure secret management systems (e.g., HashiCorp Vault). If retained, ensure encryption keys are managed separately and never committed to the repository. - Medium · Outdated Dependencies with Known Vulnerabilities —
go.mod - multiple dependencies. Multiple dependencies use older versions that may contain known security vulnerabilities: gin v1.7.0 (released 2021, multiple CVEs), sirupsen/logrus v1.7.0 (2020), and spf13/viper v1.12.0 (2022). These versions lag behind current stable releases by 2+ years. Fix: Update all dependencies to latest stable versions: gin to v1.9+, logrus to v1.9+, viper to v1.15+, and others. Run 'go list -u -m all' to identify all outdated packages and 'go get -u' to update them. Implement automated dependency scanning using dependabot or similar tools. - Medium · XML External Entity (XXE) Injection Risk —
pkg/pcap/pdml.go, pkg/pdmltree/pdmltree.go. The codebase uses 'antchfx/xmlquery' (v1.3.3) for XML parsing, primarily for parsing PDML output from tshark. If untrusted or malformed XML input is processed without proper XXE protection, this could enable XXE attacks. File 'pkg/pcap/pdml.go' likely processes tshark XML output. Fix: Review XML parsing code to ensure XXE protections are enabled. Disable external entity resolution and DTD processing in xmlquery parser configurations. Add input validation for XML from tshark output. Consider using safer XML parsing libraries if available. - Medium · Command Injection Risk in Shell Command Execution —
pkg/pcap/cmds.go, pkg/pcap/cmds_unix.go, pkg/pcap/cmds_windows.go. The codebase executes tshark commands via shell (pkg/pcap/cmds.go, pkg/pcap/cmds_unix.go). The file 'kballard/go-shellquote' is used for shell quoting, but if user-controlled input (filter expressions, file paths) is not properly sanitized before being passed to tshark, command injection is possible. Fix: Always use parameterized command execution instead of shell string concatenation. Use os/exec.Command with separate argument slices rather than building shell strings. Validate and sanitize all user inputs (display filters, capture filters, file paths). Implement allowlists for filter expressions if possible. - Medium · Potential Path Traversal Vulnerability —
pkg/confwatcher/confwatcher.go, pkg/pcap/loader.go, configs/profiles/profiles.go. The codebase handles file operations for pcap files and configuration files (pkg/confwatcher/, configs/). File paths from user input or configuration may not be properly validated, potentially allowing path traversal attacks to access arbitrary files on the system. Fix: Implement strict path validation: use filepath.Clean() and verify resolved paths are within expected directories. Use filepath.Join() safely with predefined base directories. Implement allowlists for accessible directories. Reject paths containing '../' or absolute paths if not necessary. - Low · Missing Input Validation on Filter Expressions —
pkg/pcap/cmds.go, pkg/cli/flags.go. Display filters from user input are passed to tshark. While tshark validates its own filters, the application should perform pre-validation to prevent malformed or excessively complex filters from consuming resources (DoS). Fix: Implement input validation for Wireshark display filter syntax before passing to tshark. Add length limits for filter expressions. Consider implementing a timeout for filter validation. Log suspicious filter attempts. - Low · Insecure Deserialization in Deep Comparison Library —
undefined. Dependency ' Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.