Repository navigation
feat(witan): free-text search for witan projects and witan tasks - #362
Merged
Merged
Conversation
Finding a project or task from the CLI meant paging through the full list, because the BM25 search tools the server already exposes had no CLI entry point. Both commands now take an optional positional query, e.g. `witan tasks 'grafana dashboard'`, and rank results by relevance. Task hits are filtered on the fields search rows carry (status, project) rather than intersected with `task_list`: with no repo in scope that list is the 50 most recently updated tasks, so the intersection dropped every older match. `--ready` and `--assignee` still intersect with the server's answer, because readiness and `@me` only resolve server-side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC
Search rows don't carry blocked_by. Dropping it from the table columns only hid it in txt mode: render_table dumps the row dicts for json/yaml/toml, so every search result reported an empty blocked_by, including blocked tasks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC
task_ready takes no status, so `--ready --status open` also listed blocked tasks whose blockers had closed and in_progress tasks with lapsed leases, while the new search path did honour --status. Both paths now filter the same way. task_ready truncates server-side, so it fetches every ready task before the filter runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Both new searches fail in guarded local-fallback mode because their tools are absent from the read allowlist.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds relevance-ranked free-text search to project/task CLI listings and fixes ready-task status filtering.
Changes:
- Adds optional search queries while preserving listing filters.
- Adds CLI coverage and regenerated reference documentation.
- Releases
witan-council0.36.0.
File summaries
| File | Description |
|---|---|
mcp/servers/witan/witan/cli/tasks.py |
Adds task search and status-aware readiness filtering. |
mcp/servers/witan/witan/cli/projects.py |
Adds project search. |
mcp/servers/witan/tests/test_cli.py |
Tests search, filtering, ranking, and output. |
docs/reference/cli.md |
Documents new query arguments. |
mcp/servers/witan/CHANGELOG.md |
Records the release changes. |
mcp/servers/witan/pyproject.toml |
Bumps the package to 0.36.0. |
uv.lock |
Updates the locked workspace version. |
Review details
- Files reviewed: 6/7 changed files
- Comments generated: 2
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
task_search and workflow_project_search were missing from READ_TOOLS, so when a deployment is configured and nothing routed the invocation to it, the guard refused them as writes and `witan tasks QUERY` / `witan projects QUERY` exited instead of reading the fallback store. Both tools only read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What are the relevant tickets?
N/A
Description (What does it do?)
Finding a project or task from the CLI meant paging through the whole list, even though the server already exposes BM25 search as
workflow_project_searchandtask_search. This adds an optional positional query to both listing commands, e.g.witan projects gravitinoorwitan tasks 'grafana dashboard'. Results come back in relevance order, and the existing flags (--status,--repo,--all-repos,--project,--assignee,--ready,--limit) still apply.It also fixes
witan tasks --ready --status X, which ignored--statusbecausetask_readytakes no status (so--ready --status openalso listed blocked tasks whose blockers had closed). Both the search and listing paths now filter the same way.Releases
witan-council0.36.0, so this publishes on merge.Implementation details
projectscallsworkflow_project_searchinstead ofworkflow_project_listwhen a query is given. Both take the samerepo/statusarguments.tasksfilters the search hits on the fields they carry (status,project_slug), hiding closed tasks unless--statusis passed, the same as the plain listing.--readyand--assigneeare checked againsttask_ready/task_list, because readiness and@meonly resolve on the server.task_list, and it came back empty forwitan tasks --all-repos 'grafana dashboard'against the deployed server whiletask_searchhad 20 hits. With no repo in scope,task_listreadslist_all_tasks, which ends inlimit 50(read.gq), so any match older than the 50 most recently updated tasks was dropped.test_tasks_query_finds_tasks_older_than_the_recent_windowcovers this.blocked_by, so search output leaves it out instead of printing it blank, in both the table and--output-format json|yaml|toml(which dumps the row dicts, not the columns). Thestatuscolumn still showsblocked.task_readytruncates server-side, so when--statusor a query filters its result client-side the CLI asks it for every ready task first.projectsandtasksdocstrings moved to the indented numpydoc form cyclopts parses. The one-linename: descform showed only continuation lines in--help.docs/reference/cli.mdis regenerated.How can this be tested?
uv run --isolated --package witan-council --group test pytest mcp/servers/witanon the rebased head: 1199 passed, 1 skipped. New tests intests/test_cli.pycover ranking with closed-task elision,--status closed, the no-match message, a match older than 51 newer tasks under--all-repos,--ready --status openwith and without a query, JSON search output withoutblocked_by, and project search../bin/gen_docs.py --check,just check-versions,just check-core-floor, anduv lock --checkpass.witan tasks --all-repos 'grafana dashboard'returns the open StarRocks and in-progress ClickHouse observability tasks with closed matches hidden.witan projects omnigraphreturns 4 active projects.witan tasks --ready omnigraphreturns ready tasks.witan projects gravitinoprints "No projects matching 'gravitino'";workflow_project_searchwithrepo=""andstatus=Nonereturns 0 rows for that query, so that's correct.Additional Context
--ready,--assigneeor--projectfilter them, so a narrow filter can miss a lower-ranked match.--assigneecombined with a query and--all-reposis still subject to the 50-row cap, tracked in tk-witan-tasks-all-repos-and-status-listings-are-si-faf47c (comment added with this case).--status ''is rejected by the server, so there's no way to ask for every status), tk-most-witan-cli-help-output-drops-parameter-descr-155897 (the docstring format in the rest of the CLI), and tk-structured-cli-output-carries-rich-escaped-title-16403a (a query containing[shows up Rich-escaped in the JSON/YAML/TOMLtitle).🤖 Generated with Claude Code
https://claude.ai/code/session_01SFRYTsWVvNq32z75QjgjzC