feat: boxel search can list a realm's cards without a query, and explains rejected filters#5275
feat: boxel search can list a realm's cards without a query, and explains rejected filters#5275jurgenwerk wants to merge 2 commits into
Conversation
…r errors
`boxel search` is a precise typed-query tool, but agents (and the factory) use
it to *discover* a realm's cards before they know any module URLs — and it
fought them: `--query` was required (no list-all), an empty filter 400'd, and
the realm's "cannot determine the type of filter" error said nothing about how
to fix it.
- `--query` is now optional; omitted → `{}`, which the federated-search
endpoint already treats as "every card in the realm(s)". `boxel search
--realm X` now lists everything.
- An explicit empty `filter` (`{"filter":{}}`) is normalized to list-all
instead of 400'ing.
- On the unclassifiable-filter 400, print a hint enumerating valid filter
shapes and the `on` requirement for field filters.
- Extracted `parseSearchQuery` / `searchErrorHint` as pure, unit-tested helpers.
- search skill: drop the false "or stdin" claim, document list-all discovery,
the `on` requirement, and "don't pass an empty filter".
CS-11651.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
search usable for discovery + actionable filter errorssearch supports discovery (optional --query) + actionable filter errors
There was a problem hiding this comment.
Pull request overview
This PR updates boxel-cli’s search command to support realm “discovery” by making --query optional (defaulting to a list-all query), normalizing an explicit empty filter, and appending actionable hints for a specific 400 error. It also adds unit tests for the new query normalization and error-hint behavior and updates the search skill documentation accordingly.
Changes:
- Make
--queryoptional and normalize omitted/empty/{"filter":{}}queries to list-all ({}). - Add a targeted, actionable hint for the “cannot determine the type of filter” 400 response.
- Add vitest unit coverage for query normalization and hint generation; update skill docs to describe discovery-first usage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/boxel-cli/src/commands/search.ts | Implements optional --query, normalization helper, and actionable error hinting. |
| packages/boxel-cli/tests/commands/search.test.ts | Adds unit tests for parseSearchQuery and searchErrorHint. |
| packages/boxel-cli/plugin/skills/search/SKILL.md | Updates skill documentation to describe discovery/list-all behavior and common pitfalls. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ' • all cards in the realm: omit --query (or pass {})', | ||
| ' • by type: {"filter":{"type":{"module":"<https card module url>","name":"<CardName>"}}}', | ||
| ' • by field: {"filter":{"on":{"module":"<url>","name":"<CardName>"},"eq":{"<field>":"<value>"}}}', | ||
| ' • combine: "any" (OR) / "every" (AND); also "contains", "range", "not"', | ||
| 'Field filters (eq/contains/range) require an "on" type scope, and "module" must be the full HTTPS URL of the card definition (no relative paths).', |
There was a problem hiding this comment.
(Written by Claude on Matic's behalf.)
Fixed in aedbe7f. The hint now uses a single consistent placeholder <https-module-url> in both the type and field examples, and the trailing line spells out that it's the full HTTPS URL of the card definition (no relative paths).
| Queries are JSON, passed via `--query`. **Omit `--query` to list every card in the realm(s)** — the fastest way to discover what's there (and to find a card's module URL from its `meta.adoptsFrom`) before writing a typed filter. The shape mirrors the `_search` API: | ||
|
|
There was a problem hiding this comment.
(Written by Claude on Matic's behalf.)
Fixed in aedbe7f. Regenerated the synopsis with build-plugin — the generated --query line now reads "JSON query object (as a string). Omit to list every card in the realm(s).", matching the CLI. (Only the search skill changed.)
- Use a single consistent placeholder (<https-module-url>) in the cannot-classify-filter hint instead of mixing "<https card module url>" and "<url>". - Regenerate the search skill's autogenerated command block so the --query option text reflects it's now optional (omit to list all). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
search supports discovery (optional --query) + actionable filter errors| | "give me JSON I can pipe" | add `--json` | | ||
| | Ask | Run | | ||
| | ------------------------------- | -------------------------------------------------------------------- | | ||
| | "what cards are in this realm?" | `boxel search --realm <url>` — **omit `--query`** to list everything | |
There was a problem hiding this comment.
what about the /_mtimes API? this list everything in a realm and is much cheaper
|
Also this might collide with the work to refactor boxel-cli to use the new unified search endpoint #5291 |
What was wrong
boxel searchrequired a fully-formed query — there was no way to just "list what's in a realm." And writing a query needs a card's module URL up front, so if you didn't know it you'd guess, and the server rejected the bad filter with a crypticcannot determine the type of filter400 that didn't say how to fix it.Why it matters
The software factory's agent reaches for
boxel searchto discover what cards a realm already has — before it knows any module URLs. It kept hitting both walls (required option '--query', then the cryptic 400) and stalling on what should be a simple "what's here?" lookup.What this changes
--queryis now optional — omit it to list every card in the realm(s). (An explicit empty filter,{"filter":{}}, is treated the same way.)ontype scope.Testing
{}/ empty filter → list-all) and the error-hint text.