One query language searches everything HarnessLink keeps for you: the
Query page (Dashboard → Query, g q) searches history, memories, runs
and session transcripts at once, and the search box of History,
Archive, Memory and Runs takes the same syntax for that page
alone. Plain words keep working: auth refactor finds both words.
auth refactor both words (full text)
"rate limit" the exact phrase
harness:codex a field equals a value
workspace:*superpi* wildcards: * any run, ? one character
cwd:/\/Workspace\/(api|web)/i a regex on a field
/fix(ed)? the (cache|queue)/i a regex on the main text
tokens:>10000 cost:>=1.5 numeric comparisons
created:2026-10-01..2026-10-26 a range (numbers or dates)
after:-7d before:2026-10-20 time bounds, relative or absolute
in:history in:runs sources (Query page only)
has:session -has:cwd the field is set / not set
-harness:omp NOT "draft" exclusion
(harness:codex OR harness:omp) AND /timeout/iCombining terms
Terms side by side must all match (an implicit AND). OR matches either
side; NOT or a leading - excludes. Parentheses group.
Precedence, tightest first: parentheses, NOT, AND, OR. So
harness:omp OR harness:codex timeout means "omp, or codex with timeout",
while (harness:omp OR harness:codex) timeout means "timeout in omp or
codex". NOT harness:omp timeout means "timeout, not in omp".
AND, OR and NOT are keywords only in capitals: this or that searches
for three words.
Text
A bare word matches the page's main text: the prompt on History and Archive,
the memory's body on Memory, the run id and session titles on Runs, the
session title for transcripts on Query. History and memories use the
full-text index: a word matches whole words (fix does not match fixed),
case-insensitively. Add * for a prefix: fix* matches fix, fixed,
fixes. Runs and transcripts match words as case-insensitive substrings.
"…" matches a phrase, in order. Inside quotes a backslash makes the next
character literal (\" is a quote); nothing else is special.
Fields
field:value compares one field. The value may be quoted to include spaces
(harness:"Claude Code"). Field names are a fixed list per page; an unknown
one is an error that points at it.
| Page | Fields |
|---|---|
| History, Archive | workspace harness device session cwd prompt created |
| Memory | project harness type device temp title body path updated |
| Runs | harness phase roster workspace run tokens cost sessions updated |
| Query | all of the above, plus in:. Transcripts have workspace harness title session updated |
Every page also accepts has:, before: and after:.
How a value matches depends on the field:
- Labels (
harness,phase,roster,type,workspace,project,device): equal, ignoring case. Names work as well as ids:harness:"Claude Code",type:"Work state",workspace:api(the label) orworkspace:git:github.com/acme/api(the id),project:the project's friendly name or its folder slug,device:a hostname or device id. - Ids (
session,run): exactly equal, case-sensitive. - Text (
prompt,cwd,title,body,path): contains the value,ignoring case.
prompt:Timeoutmatches "fix the timeout". - Numbers (
tokens,cost,sessions): see below. - Times (
created,updated): see below. temp:temp:trueortemp:false(also1/0,yes/no).
On Runs, a run matches a session field when any of its sessions does
(harness:codex), and -harness:codex keeps runs where none does.
tokens (input + output + cache), cost, sessions (count) and updated
(last activity) are the run's totals.
Wildcards
* matches any run of characters and ? exactly one, across the whole
value: workspace:*superpi*, cwd:/src/*, session:s?. On text fields
without a wildcard the value is a substring already. \* and \? are a
literal star and question mark.
Numbers, times and ranges
Number and time fields take N, >N, >=N, <N, <=N or a range a..b
(both ends included; either end may be left open: tokens:10000..,
cost:..0.5).
A time is one of:
- a date,
2026-10-01(a whole UTC day), or a month,2026-10; - a date and time in UTC,
2026-10-01T09:30(that minute) or2026-10-01T09:30:15; - unix seconds,
1790812800; - relative to now:
-30m,-2h,-7d,-2w,-3mo(30-day months),-1y; also-45s.
A time covers its whole span: created:2026-10-01 is that day,
created:>2026-10-01 starts the next day, created:<=2026-10-01 includes it,
and created:2026-10-01..2026-10-26 runs through the end of the 26th. A
relative time on its own means "since then": created:-7d is the last
seven days.
after:X keeps rows at or after the start of X, before:X rows before the
start of X, on the page's time: when a prompt was typed (History, Archive),
when a memory file or transcript last changed, a run's last activity. They
work beside the date-range picker, which narrows further.
has:
has:field keeps rows where the field is set and not empty (has:session,
has:cwd); -has:field keeps rows where it is missing. For numbers it means
"not zero" (has:cost).
Regular expressions
/pattern/flags is a JavaScript regular expression, on the main text when
bare, on a field after field:. Flags: i (ignore case), m, s, u.
- A word that starts with
/is a regex only when it ends in/plusvalid flags, so
cwd:/src/apiis still a path. Quote a value to be sure:cwd:"/tmp/i". - Patterns are at most 256 characters. Backreferences (
\1) and nestedquantifiers that can take exponential time, like
(a+)+,(.*)*or(\w+\s?)*, are refused with an error. - The database cannot run regular expressions, so HarnessLink narrows the
candidates with everything else in the query (and with the literal text a pattern must contain), then tests the rest, newest first. It tests at most 20,000 rows per search (or about 200 ms); past that the page says Scanned the newest N rows and the counts, fields and chart cover those rows only. Add a field or a date range to search further back.
- Sorting by relevance does not apply to regex searches; they list newest
first.
Query page sources
On the Query page, in:history, in:memories, in:runs and in:sessions
pick sources; several in: terms combine like any other term, so
in:history OR in:runs searches both. The Source filter does the same.
A field that one source does not have is simply false there: tokens:>1000
finds only runs, and -tokens:>1000 keeps everything else. Memories have no
workspace, and runs and transcripts no device.
Results from every source are listed together, newest first, or by relevance when the query has words: each source ranks its own matches and the list interleaves them, so the first page shows the best of each.
Errors
A query that cannot be read is underlined where the problem is, with a
message such as Unknown field "harnes". Fields here: …,
OR needs a term after it, Unclosed parenthesis or
created: needs a date …. Fix that part and search again.
Limits
A query is at most 2,000 characters, 32 terms and 24 levels of nesting. A query that needs too many separate comparisons is refused as too complex.