Filtering the timeline¶
timeline can write only part of the timeline, which keeps the output of a
busy host to the incident window. A time window is set with --since and
--until, rows without a timestamp are kept with --keep-undated, and a
pattern over the row text is set with --match:
--since WHENand--until WHENkeep rows withsince <= timestamp_utc <= until. Either may be given alone. Rows without a timestamp are dropped once either is given, unless--keep-undatedis passed. Formats without per-message times (Continue, Zed, Cline's legacy history) give their rows the session's timestamp, so those rows are kept or dropped by the time the session started.--match REGEXkeeps rows whosetextmatches the Python regular expression (resyntax, searched anywhere in the text, so anchor with^and$for a whole match). Repeat it to keep rows that match any of the patterns;-imakes every pattern case-insensitive. A matchedtool_userow keeps itstool_resultrow, and a matched result its call, when the partner has the samesession_idandtool_use_id(the samesource_filefor rows without a session id) and is inside the time window. Onlytextis searched; filter other fields with jq afterwards.--matchapplies after the time window.sessions.jsonlis summarised from the rows that are kept, so its counts and first and last timestamps describe the filtered timeline, not the whole session.
The resolved window is printed as a window: line, so a relative value
such as 3d can be checked and recorded in case notes. A value that is not
one of the forms below, a --since later than the --until, or a
--match that is not a valid regular expression stops the command with
exit code 2 before the input is opened or extracted.
WHEN forms¶
WHEN is one of the following, after surrounding whitespace is trimmed;
day words, units, ago, Z and UTC may be in any case. Nothing else is
accepted, and nothing is guessed. A value without an offset is UTC, like
the timeline.
| Form | Examples | Meaning |
|---|---|---|
| ISO 8601 date | 2026-10-01, basic 20261001, week date 2026-W40-1, ordinal 2026-274 |
That day. |
| Year or month | 2026, 2026-10 |
That year or month. |
Date and time, T or one space between them |
2026-10-01T09, 2026-10-01T09:30, 2026-10-01 09:30, 2026-10-01 09:30:15, 2026-10-01T09:30:15.250, basic 20261001T093015 |
Seconds are optional and may carry a fraction. |
| Date and time with a UTC offset, directly after the time or after one space | 2026-10-01T09:30Z, 2026-10-01T09:30+02:00, 2026-10-01T09:30-0500, 2026-10-01T09:30+02, 2026-10-01 09:30 +02:00, 2026-10-01 09:30 UTC |
Offsets are Z, UTC (after a space only), +HH:MM, +HHMM or +HH; - is west of UTC. The time is converted to UTC. |
| Epoch number | 1759312800, 1759312800000 |
Seconds since 1970; a number above 10^11 is milliseconds. |
| Day word | today, yesterday |
That UTC calendar day. |
now |
now |
The current time. |
| Relative time | 45m, 45min, 45 minutes, 36h, 36 hours, 3d, 3 days ago, 2w, 6mo, 6 months ago, 1y, 2 years |
That long before now. The space and a trailing ago are optional; units are m, min, minute(s) (minutes), h, hour(s), d, day(s), w, week(s), mo, month(s), y, year(s). m is always minutes and mo always months. Months and years move the calendar date and keep the time of day; a day the target month lacks becomes its last day, so 31 March less 1mo is 28 February (29 in a leap year). |
Periods and instants¶
An absolute value or a day word names a period as long as its last written
unit: a year, a month, a day, an hour (T09), a minute (09:30) or a
second (09:30:15). --since takes the period's first millisecond and
--until its last, so --since 2026-10-01 --until 2026-10-01 selects
that whole day, --until 2026-10 runs to the end of October, and
--until "2026-10-01 09:30" keeps an event at 09:30:40. A time with a
fraction of a second, now, a relative time and an epoch number are
instants, used as they are. Dates and times are parsed by
dateutil.parser.isoparse and months and years counted by
dateutil.relativedelta, both from python-dateutil; the forms
themselves are defined in doubleagent/filters.py.