wtftools 0.0.0__py3-none-any.whl

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,134 @@
1
+ # bash completion for `wtf` / `wtftools`
2
+ # Install: copy to /etc/bash_completion.d/ or `source` from your bashrc.
3
+
4
+ _wtf_complete() {
5
+ local cur prev cmd
6
+ COMPREPLY=()
7
+ cur="${COMP_WORDS[COMP_CWORD]}"
8
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
9
+
10
+ local subcommands="info audit problems crontab doctor services config logs explain history diff top ports events"
11
+ local global_opts="-h --help -V --version --no-color -v --verbose -q --quiet --config"
12
+
13
+ if [[ $COMP_CWORD -eq 1 ]]; then
14
+ COMPREPLY=( $(compgen -W "$subcommands $global_opts" -- "$cur") )
15
+ return 0
16
+ fi
17
+
18
+ cmd="${COMP_WORDS[1]}"
19
+
20
+ case "$cmd" in
21
+ info)
22
+ COMPREPLY=( $(compgen -W "--format" -- "$cur") )
23
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
24
+ ;;
25
+ audit|problems)
26
+ local opts="--format --strict --exit-zero --check --only --since --list-checks --brief -b --ignore --serial --check-timeout --alert --alert-on --save --output -o"
27
+ case "$prev" in
28
+ --format) COMPREPLY=( $(compgen -W "text json prometheus csv plain html" -- "$cur") ); return 0 ;;
29
+ --only) COMPREPLY=( $(compgen -W "fail warn problems problem skip ok all" -- "$cur") ); return 0 ;;
30
+ --alert-on) COMPREPLY=( $(compgen -W "fail warn any" -- "$cur") ); return 0 ;;
31
+ --output|-o) COMPREPLY=( $(compgen -f -- "$cur") ); return 0 ;;
32
+ --check|--ignore)
33
+ local names="uptime system load iowait psi tcp-retrans memory swap disks \
34
+ inodes readonly-mounts failed-units enabled-inactive restart-loops network-errors conntrack \
35
+ journal-disk zombies d-state oom kernel-errors kernel-taint cert-expiry fds pids auth time-sync \
36
+ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-probes fail2ban"
37
+ COMPREPLY=( $(compgen -W "$names" -- "$cur") )
38
+ return 0
39
+ ;;
40
+ esac
41
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
42
+ ;;
43
+ explain)
44
+ local opts="--check --ignore --since --all --prompt --format --serial --check-timeout --llm --llm-model --llm-timeout"
45
+ case "$prev" in
46
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
47
+ --llm) COMPREPLY=( $(compgen -W "ollama claude openai auto" -- "$cur") ); return 0 ;;
48
+ --check|--ignore)
49
+ local names="uptime system load iowait psi tcp-retrans memory swap disks \
50
+ inodes readonly-mounts failed-units enabled-inactive restart-loops network-errors conntrack \
51
+ journal-disk zombies d-state oom kernel-errors kernel-taint cert-expiry fds pids auth time-sync \
52
+ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-probes fail2ban"
53
+ COMPREPLY=( $(compgen -W "$names" -- "$cur") )
54
+ return 0
55
+ ;;
56
+ esac
57
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
58
+ ;;
59
+ diff)
60
+ local opts="--snapshot --against --format"
61
+ case "$prev" in
62
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
63
+ --against) COMPREPLY=( $(compgen -f -- "$cur") ); return 0 ;;
64
+ esac
65
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
66
+ ;;
67
+ history)
68
+ COMPREPLY=( $(compgen -W "--limit --format" -- "$cur") )
69
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
70
+ ;;
71
+ top)
72
+ local opts="--sort --limit --user --name --format"
73
+ case "$prev" in
74
+ --sort) COMPREPLY=( $(compgen -W "cpu rss" -- "$cur") ); return 0 ;;
75
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
76
+ --user) COMPREPLY=( $(compgen -u -- "$cur") ); return 0 ;;
77
+ esac
78
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
79
+ ;;
80
+ ports)
81
+ local opts="--proto --public-only --format"
82
+ case "$prev" in
83
+ --proto) COMPREPLY=( $(compgen -W "tcp udp all" -- "$cur") ); return 0 ;;
84
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
85
+ esac
86
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
87
+ ;;
88
+ services)
89
+ local opts="-n --lines --format"
90
+ case "$prev" in
91
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
92
+ esac
93
+ local units=$(systemctl list-units --type=service --no-legend --plain 2>/dev/null \
94
+ | awk '{ sub(/\.service$/, "", $1); print $1 }')
95
+ COMPREPLY=( $(compgen -W "$opts $units" -- "$cur") )
96
+ ;;
97
+ events)
98
+ local opts="--since --kind --limit --format"
99
+ case "$prev" in
100
+ --kind) COMPREPLY=( $(compgen -W "reboot oom failed-unit kernel-err auth-fail login" -- "$cur") ); return 0 ;;
101
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
102
+ esac
103
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
104
+ ;;
105
+ logs)
106
+ local opts="--since --priority -p --units --lines -n --format"
107
+ case "$prev" in
108
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
109
+ --priority|-p) COMPREPLY=( $(compgen -W "emerg alert crit err warning notice info debug" -- "$cur") ); return 0 ;;
110
+ esac
111
+ COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
112
+ ;;
113
+ doctor)
114
+ COMPREPLY=( $(compgen -W "--format --check-updates" -- "$cur") )
115
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
116
+ ;;
117
+ crontab)
118
+ local opts="-S --system -U --user-file -u --username --format --strict --exit-zero"
119
+ case "$prev" in
120
+ -S|--system|-U|--user-file) COMPREPLY=( $(compgen -f -- "$cur") ); return 0 ;;
121
+ -u|--username) COMPREPLY=( $(compgen -u -- "$cur") ); return 0 ;;
122
+ --format) COMPREPLY=( $(compgen -W "text json" -- "$cur") ); return 0 ;;
123
+ esac
124
+ COMPREPLY=( $(compgen -f -W "$opts" -- "$cur") )
125
+ ;;
126
+ config)
127
+ COMPREPLY=( $(compgen -W "--example --format" -- "$cur") )
128
+ [[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
129
+ ;;
130
+ esac
131
+ }
132
+
133
+ complete -F _wtf_complete wtf
134
+ complete -F _wtf_complete wtftools
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: wtftools
3
+ Version: 0.0.0
4
+ Summary: One command to see what is going on with your Linux server right now.
5
+ Author-email: Aleksandr Pimenov <wachawo@gmail.com>
6
+ Maintainer-email: Aleksandr Pimenov <wachawo@gmail.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2026 Aleksandr Pimenov
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Homepage, https://github.com/wachawo/wtftools
30
+ Project-URL: Repository, https://github.com/wachawo/wtftools.git
31
+ Project-URL: Documentation, https://github.com/wachawo/wtftools#readme
32
+ Project-URL: Bug Reports, https://github.com/wachawo/wtftools/issues
33
+ Keywords: devops,sre,linux,diagnostics,monitoring,cron,system,audit,cli
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Intended Audience :: System Administrators
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3.8
40
+ Classifier: Programming Language :: Python :: 3.9
41
+ Classifier: Programming Language :: Python :: 3.10
42
+ Classifier: Programming Language :: Python :: 3.11
43
+ Classifier: Programming Language :: Python :: 3.12
44
+ Classifier: Operating System :: POSIX :: Linux
45
+ Classifier: Topic :: System :: Systems Administration
46
+ Classifier: Topic :: System :: Monitoring
47
+ Classifier: Topic :: Utilities
48
+ Requires-Python: >=3.8
49
+ Description-Content-Type: text/markdown
50
+ License-File: LICENSE
51
+ Provides-Extra: full
52
+ Requires-Dist: psutil>=5.9.0; extra == "full"
53
+ Provides-Extra: dev
54
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
55
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
56
+ Requires-Dist: coverage>=7.0.0; extra == "dev"
57
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
58
+ Requires-Dist: build>=1.0.0; extra == "dev"
59
+ Requires-Dist: stdeb>=0.10.0; extra == "dev"
60
+ Requires-Dist: pre-commit>=3.0.0; extra == "dev"
61
+ Dynamic: license-file
62
+
63
+ # wtftools
64
+
65
+ > One command to see what is going on with your Linux server right now.
66
+
67
+ **Status:** v0.0.0 — initial public release. 14 subcommands, 38 built-in
68
+ checks, snapshot/diff/history, LLM-driven explain. One-shot CLI; no daemon,
69
+ no fleet aggregator, no plugin extension API.
70
+
71
+ > **In a hurry?** See [docs/QUICKSTART.md](docs/QUICKSTART.md) for the 5-minute version.
72
+
73
+ ```
74
+ $ wtf
75
+ ─────────── AUDIT ────────────
76
+ [ OK ] uptime 3d 4h 12m
77
+ [ OK ] load average 0.42 0.51 0.55 / 8 CPU
78
+ [ OK ] memory 4.1GB / 16.0GB used (25%)
79
+ [WARN] disk /var 17.0GB / 20.0GB used (85%)
80
+ [ OK ] zombie processes 0 zombies
81
+ [FAIL] failed systemd units 1 failed unit(s)
82
+ [ OK ] crontab syntax 14 cron line(s), no errors
83
+
84
+ Summary: 12 ok · 1 warn · 1 fail · 2 skip
85
+ ```
86
+
87
+ ## Subcommands
88
+
89
+ | command | what it does |
90
+ |---------------------|-------------------------------------------------------------|
91
+ | `wtf` / `wtf audit` | green/yellow/red checklist: what is OK and what is not |
92
+ | `wtf problems` | alias for `audit --only problems` — show WARN+FAIL only |
93
+ | `wtf explain` | per-check actionable advice; `--llm` to pipe to LLM |
94
+ | `wtf info` | one-page snapshot: host, uptime, load, mem, disks, top, net |
95
+ | `wtf top` | focused process top: sort by cpu/rss, filter user/name |
96
+ | `wtf ports` | listening sockets with owning PID/user/command |
97
+ | `wtf services NAME` | drilldown one service: state, restarts, mem, ports, journal |
98
+ | `wtf logs` | recent ERROR+ journal entries grouped by service |
99
+ | `wtf events` | chronological timeline: reboots, OOM, failed units, … |
100
+ | `wtf history` | list saved audit snapshots (`wtf audit --save` to create) |
101
+ | `wtf diff` | compare current state to a saved snapshot |
102
+ | `wtf crontab` | validate all standard crontab locations + per-user crontabs |
103
+ | `wtf doctor` | self-diagnostic: which tools wtftools can actually use |
104
+ | `wtf config` | show effective config / print example |
105
+
106
+ `wtftools` absorbs and supersedes [`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron validator now lives at `wtf crontab`.
107
+
108
+ ## Install
109
+
110
+ ### From PyPI
111
+
112
+ ```bash
113
+ pip install wtftools # core, stdlib-only
114
+ pip install wtftools[full] # + psutil for richer metrics
115
+ ```
116
+
117
+ After install the short command `wtf` (and the long alias `wtftools`) is on `$PATH`.
118
+
119
+ ### From apt (Debian/Ubuntu)
120
+
121
+ ```bash
122
+ sudo apt install python3-psutil
123
+ sudo dpkg -i wtftools_0.0.0-1_all.deb
124
+ ```
125
+
126
+ A `.deb` is built from the same source via `scripts/build-deb.sh` (uses `stdeb`).
127
+
128
+ ### From source
129
+
130
+ ```bash
131
+ git clone https://github.com/wachawo/wtftools
132
+ cd wtftools
133
+ pip install -e .
134
+ # or test without installing:
135
+ python3 wtf.py audit
136
+ ```
137
+
138
+ ## Usage
139
+
140
+ ```bash
141
+ wtf # short audit summary (default)
142
+ wtf problems # only WARN+FAIL rows
143
+ wtf info # detailed system snapshot
144
+ wtf info --format json # machine-readable
145
+
146
+ wtf audit # full audit with [OK]/[WARN]/[FAIL] markers
147
+ wtf audit -v # show extra detail (failed units, OOM events)
148
+ wtf audit --strict # exit 1 on warnings (CI-friendly)
149
+ wtf audit --format json # JSON output for pipelines
150
+ wtf audit --check memory --check disks # run named checks only
151
+ wtf audit --list-checks # show all available check short-names
152
+ wtf audit --since 1 # look-back window for OOM/auth/kernel (default 24h)
153
+ wtf audit --brief # one-line summary for MOTD / SSH banners
154
+ wtf audit --ignore swap --ignore "disk /mnt/Backup" # silence specific checks
155
+ wtf audit --format csv > audit.csv # spreadsheet-friendly
156
+ wtf audit --format plain | awk '$1=="fail"' # shell-pipeline-friendly
157
+ wtf audit --format html -o report.html # self-contained HTML for tickets
158
+
159
+ wtf audit --save # save snapshot to ~/.cache/wtftools/
160
+ wtf diff # what changed vs last snapshot
161
+ wtf diff --snapshot 5 # vs 5 snapshots ago
162
+ wtf history # list saved snapshots
163
+
164
+ wtf explain # per-check actionable advice
165
+ wtf explain --prompt | ollama run llama3 # pipe to local LLM
166
+ wtf explain --llm ollama # built-in: call ollama directly
167
+ wtf explain --llm claude # anthropic SDK + ANTHROPIC_API_KEY
168
+ wtf explain --llm auto # try ollama → claude → openai
169
+
170
+ wtf audit --alert 'mail -s "wtf $WTF_HOST" sre@example.com'
171
+ wtf audit --alert-on warn --alert 'curl -X POST $SLACK_WEBHOOK -d @-'
172
+
173
+ wtf top # top processes
174
+ wtf top --sort rss --user www-data --limit 5 # top RAM consumers for one user
175
+ wtf ports # listening TCP + owning process
176
+
177
+ wtf services nginx # state + restarts + ports + last 20 journal lines
178
+ wtf logs # last hour, ERROR+
179
+ wtf events --since 48 # 48-hour incident timeline
180
+ wtf events --kind oom --kind failed-unit # filter to specific kinds
181
+
182
+ wtf doctor # show which CLI tools wtf can use on this host
183
+ wtf doctor --check-updates # also query PyPI for a newer version
184
+ ```
185
+
186
+ ## Exit codes
187
+
188
+ | code | meaning |
189
+ |------|--------------------------------------------------|
190
+ | 0 | everything OK (`audit`) / no errors (`crontab`) |
191
+ | 1 | warnings with `--strict`, or crontab errors |
192
+ | 2 | audit found a `[FAIL]` |
193
+ | 130 | interrupted (Ctrl-C) |
194
+
195
+ ## Built-in checks
196
+
197
+ uptime · system state · load average · CPU iowait · PSI cpu/memory/io ·
198
+ TCP retransmits · memory · swap · disk (per mount) · inodes ·
199
+ read-only mounts · failed systemd units · enabled-but-down services ·
200
+ restart loops · network errors · conntrack · journal disk usage · zombies ·
201
+ D-state processes · OOM kills · kernel errors · kernel taint · cert expiry ·
202
+ open file descriptors · process count · failed auth · time sync ·
203
+ pending updates · reboot required · cron daemon · crontab syntax · docker ·
204
+ hw temperatures · disk SMART · DNS · HTTP/TCP probes · fail2ban.
205
+
206
+ Run `wtf audit --list-checks` for the full list of short names usable with
207
+ `--check` and `--ignore`.
208
+
209
+ ## Config
210
+
211
+ Drop an INI at any of:
212
+
213
+ - `/etc/wtftools/config.ini`
214
+ - `/etc/wtf/config.ini`
215
+ - `~/.config/wtftools/config.ini`
216
+
217
+ Or stack one ad-hoc via `wtf --config /path/to.ini …`. Run `wtf config --example`
218
+ for a fully-commented template. Headlines:
219
+
220
+ ```ini
221
+ [thresholds]
222
+ disk_warn = 85
223
+ disk_fail = 95
224
+ swap_warn = 50
225
+ swap_fail = 90
226
+ tcp_retrans_warn = 1.0
227
+ tcp_retrans_fail = 5.0
228
+
229
+ [ignore]
230
+ checks = swap, updates
231
+ result_names =
232
+ disk /mnt/Backup
233
+ disk /mnt/Video
234
+ ```
235
+
236
+ ## Compatibility
237
+
238
+ - Python 3.8+
239
+ - Linux (any systemd-based distribution is the happy path; the tool degrades
240
+ gracefully when `systemctl` / `journalctl` are missing)
241
+ - No network access required for the core CLI
242
+ - Optional network: `wtf explain --llm claude/openai`, `wtf doctor --check-updates`
243
+
244
+ ## License
245
+
246
+ MIT
@@ -0,0 +1,20 @@
1
+ wtftools/__init__.py,sha256=I3Rlis3V3k-KwcZBZXAw3vW2tfer0qK2su7Lbw7P-bE,1948
2
+ wtftools/__main__.py,sha256=Zny7E8bCqptmdOXhKiRmZuKlj7iwBa-3Wz1oc9D_mH0,185
3
+ wtftools/audit.py,sha256=SZyU0gCxysZE9U4FWSuJ28HQjgZviFS7w5xvl7dzIPk,33820
4
+ wtftools/colors.py,sha256=752lq10R0hytgIG-nkug2JvlwM5EjJvQfa8Dyu2pSBQ,2740
5
+ wtftools/config.py,sha256=deq0vFCZNgNPy3Xo89MvAy7wlvF_Pb_e1REIcBSKwrU,7706
6
+ wtftools/cron.py,sha256=qPNSDGWSqn1tXquwQJNZzGet6XCL2NPYD4XSkqqBphs,15375
7
+ wtftools/events.py,sha256=AwXtGaeLZelpGaTems1ubL9O1hw3cug8hCbXxTY42ws,8031
8
+ wtftools/explain.py,sha256=dPoNQFN5c-X6pdp7_wWWGZl6Lf_HHRsx7pk7FH_p7Iw,13919
9
+ wtftools/info.py,sha256=FbiRhn2uoPMsvdPhXPPrhAVglmfjW0gcNpVmW1HlAnU,3662
10
+ wtftools/llm.py,sha256=_hiZ89EkNG4xOwTbNGpdY5HOzcHmxUN7ujOKIJZNDEQ,5139
11
+ wtftools/main.py,sha256=aLOP26hh4dPFxgw0w-Ir43OEYXVJb7fe2unrzNIGjBA,55165
12
+ wtftools/snapshot.py,sha256=szRgR_8i3uFgZAy1AZ1Gzr64HE36YXlOAsC66lirJxU,7012
13
+ wtftools/sysinfo.py,sha256=yAPyfkbJTd4zVtwhkxqz-3HupRAHz16-0mEGLHvPYsk,52665
14
+ wtftools-0.0.0.data/data/share/bash-completion/completions/wtf.bash-completion,sha256=qm5s6_PKCcXR6b8PDDwnptgKJW2KMjbT-PV8AQ3pyCM,6712
15
+ wtftools-0.0.0.dist-info/licenses/LICENSE,sha256=kidhJqld71of5BOrDWhyJAz5KP9J3pB08ZbhlaAmm6o,1074
16
+ wtftools-0.0.0.dist-info/METADATA,sha256=XC1Y-T8G2rrySAUgOB9dkSv7lD9GCpK1zNC7JUwo23g,10374
17
+ wtftools-0.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
18
+ wtftools-0.0.0.dist-info/entry_points.txt,sha256=rhtScgQIS_9SycAviC9jZMYeubphov_WY9zg0afvN3U,73
19
+ wtftools-0.0.0.dist-info/top_level.txt,sha256=1izOHsJ1yHhW1Ydbk0L1E-sB5XkJUwhVEFzC0MN3Tu8,9
20
+ wtftools-0.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ wtf = wtftools.main:main
3
+ wtftools = wtftools.main:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aleksandr Pimenov
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.
@@ -0,0 +1 @@
1
+ wtftools