Repository navigation
Winnow 0.4.0
Six weeks after 0.3.0, and the change you notice first is how Winnow reads. The Timeline tells a story instead of printing rows, the histogram is built in, and nearly every dialog now shares one two-pane layout with a live preview. Underneath, a pre-release review closed a long list of defects, and large cases got much faster, measured on generated EvtxECmd exports up to 10 GB.
What's new since 0.3.0
The Timeline reads as a story. Each line says what happened instead of printing the raw row. The day is written once, a Gap column says how long passed since the line above, and a run of repeats can fold into one line (×N). An overview strip shows the lines over time. A details pane lets you tag the row, note it, or open it in its table. "What else happened then" pulls in every untagged row, from every table, within a window around a finding.
The histogram is built in. It is a toolbar toggle now, not a plugin. Colour its bars by tag, by a column's values or by the first groups, and see where the grid is on the strip. It answers about five times faster and keeps answers it has already worked out.
Search keeps up. A search that runs past five seconds moves to the background and waits for Apply. Ctrl+F opens Winnow's search box instead of the browser's. Search all can be scoped to the tables you choose. A table whose search index isn't built yet is scanned on every core at once: on a 10 GB table that took a search from 17–19 s down to 4–5.6 s on four cores. Searches that do have an index are faster too.
More ways in. IIS web server logs are recognised by the names IIS gives them. FortiGate-style key=value logs get a column per key. Any other file can be imported as raw text, one line per row. A .tsv is read as tab-separated. Import and Import a folder are two-pane, with a file picker that filters and sorts.
Merging and saving tables. Merge tables whose columns don't match, with a new merge builder that can filter the table list by folder and handles merges past 500 tables. Save a view, or a selection of rows, as a new table. Export every table to one workbook, or a SQL result to Excel. Copy a column's unique values, or another table's column layout.
Derived columns. New operations: Coalesce across several columns, Row as JSON, one column per named regex capture group, URL decode and Base64 decode. Derived columns can be renamed, land next to the column they came from, preview against the rows on screen, and fill in without leaving the table.
The grid. Excel-style cell selection from the keyboard, and row selection from the gutter, where ranges add and picks stick. Filter by several tags at once (or by none), exclude a tag by right-clicking its chip, press z to undo the last filter change, and press Shift with a tag's key to take the tag back off. Each new tag gets its own colour and the next free key. A table-menu switch hides empty rows, and row striping is a setting saved per skin.
Analysis tabs. First/Last can total a column, count unique values and list each group's distinct values, and it works in the background. Pivot filters on tags and computes every subtotal level in one scan. Dashboards repaint their last results instead of re-running, plugins can offer boards of their own, and the KAPE triage board went from 26 cards to 10. Profiles say what applying one will do to the case. The Watchlist opens on its findings, scans in the background, groups hits by table and shows where each one matched. The Claude assistant example adds a SQL Copilot to the SQL pane.
One look throughout. Settings, the table menu, the Tables manager, the home screen, Import, profiles, the widget editor, Timeline configuration and the last of the older dialogs now share one two-pane frame. A plugins manager replaces the list in Settings. Notes have a live preview beside the editor. There is a new theme, Jenna, and Harvest is softer. Settings lists every keyboard shortcut and can shut Winnow down.
Big cases. Wide tables build only the columns on screen. EvtxECmd imports index EventId and the first timestamp column up front, so dashboards and time sorts stay fast. Grid pages, merged views, First/Last, Pivot, the tag rail and the histogram all do less work per request.
Windows. Open With says "Winnow", not "Python". A double-click launch with no console starts cleanly, a stalled console no longer freezes the app, and Winnow warns when it runs as administrator, which blocks dropping files onto it.
A manual. The user guide lives in docs/wiki, is published as the GitHub wiki, and from this release is also a site at https://winnow.jacson.tech, with a page and a recording for each feature.
Hardening in this release
A pre-release review fixed findings across the app. The ones worth knowing about:
- A link in case notes could run script when hovered, because the Markdown renderer didn't escape quotes in URLs. Notes travel with case files, so update before exchanging cases.
- Loading or comparing a session matched tables by their file alone, so tables imported from one SQLite database or workbook could swap tags or lose them. Sessions now match table to table.
- Imports no longer lose rows on odd input: an XLSX sheet that declares the wrong size, SQLite text that isn't UTF-8, JSON with lone surrogate escapes, a field over 128 KB, or a damaged archive.
- 12-hour timestamps with fractions of a second ("1:22:01.123 PM") were read twelve hours early in derived columns, the timeframe filter and the display.
- One unreadable value no longer leaves a derived column stuck building.
- A regex that could backtrack for minutes is refused instead of freezing the app.
- Formulas in export headers, tag names and SQL pane CSVs are neutralised.
- A runaway SQL pane query can be stopped, and a slow result can no longer paint over a newer one or land in another case.
- A case opened at startup, including by double-click, runs with that case's own plugin settings.
- An update or backup stopped part-way puts the install back, rollback restores the install manifest, and files a release no longer ships are removed.
- A case another Winnow window has open can't be deleted, and with two windows open each case keeps its own tags.
For plugin authors
The plugin API goes from 7 to 14. New since 0.3.0: api.register_dashboard and api.register_page_panel; the tab context's sqlPage, notesPage, notify, tabState, dropdownMenu and sectionPanes; a dashboard widget's live flag; and the signals render kind. One change can break a plugin: SQL pane results are held on the server now, so sqlPage results carry total and stopped, rows is the first 5,000, and sqlPage.selectedRows() is async. The saved-views API, which nothing in the app used, is gone; saved filters cover it. The table_histogram example is retired in favour of the built-in histogram.
Upgrading
Case files from 0.3.0 open as they are. python update.py updates in place, or download the archive below. Winnow needs Python 3.10 or newer (0.3.0's notes said 3.9, which was wrong: it never started on 3.9) and the packages in requirements.txt, where FastAPI is now held below 0.147 because 0.147 changed how form defaults are read.