Repository navigation
feat: add issues --search full-text search - #37
Closed
seraph-pixelperfect wants to merge 1 commit into
Closed
seraph-pixelperfect wants to merge 1 commit into
seraph-pixelperfect wants to merge 1 commit into
Conversation
Implement --search <text> on the issues command via Linear's ranked searchIssues query (the current form of the deprecated issueSearch root field), composing the existing IssueFilter from fetchIssues and reusing ISSUE_LIST_FIELDS. Missing/blank --search values fail loud rather than being silently dropped, and an empty search result gains a search-specific hint. Establishes the stubbed-global-fetch pattern in test/issues-search.test.ts for testing command/transport code without network.
This was referenced Aug 19, 2026
This was referenced Aug 20, 2026
Collaborator
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.
Closes #17
What changed
src/commands/issues.ts:--search <text>added toKNOWN_FLAGSandISSUES_HELP(usage line, flag entry, example). A missing or blank--searchvalue fails loud (VALIDATION_ERROR) instead of being silently dropped, matching the codebase's "rejected, never dropped" convention for repeatable flags. Empty search results now get a search-specific hint (No matches for "x" — try a shorter term or drop a filter).src/linear.ts:IssueListFiltergainssearch?: string. When set,fetchIssuesissues asearchIssues(term: $term, filter: { ... }, first: $first)query instead ofissues(...), composing the exact sameIssueFilterand reusingISSUE_LIST_FIELDS. Without--search, the existingissuesquery (orderBy: updatedAt) is untouched.test/issues-search.test.ts: new suite (8 tests) that establishes the repo's first network-free GraphQL test pattern —vi.stubGlobal('fetch', ...)a fake Linear endpoint, then assert on the captured query document and variables. Covers: search-only dispatch, search composed with team+state+label, plainissuesstill used without search, KNOWN_FLAGS acceptance + rendering,--assignee meviewer round trip before search, missing/blank value rejection, and unknown-flag rejection alongside--search.What I found about the schema (deviation from the issue's letter, flagged deliberately)
The issue says to implement via
issueSearch(term:). I verified the live schema via Linear's official SDK (@linear/sdk@90.0.0, whose typed documents are generated from the production schema), unpacked from npm — source: https://unpkg.com/@linear/sdk@90.0.0/ and the SDK's schema reference at https://studio.apollographql.com/public/Linear-API/schema/reference?variant=current:issueSearchdoes acceptfilter: IssueFilter+first: Int(plusafter,before,includeArchived,last,orderBy) — so the issue'sor/icontainsfallback is not needed.query, notterm(query issueSearch($after: String, $before: String, $filter: IssueFilter, $first: Int, $includeArchived: Boolean, $last: Int, $orderBy: PaginationOrderBy, $query: String)).searchIssuesinstead."searchIssuesis the recommended replacement and accepts everything we need:searchIssues(term: String!, filter: IssueFilter, first: Int, ...), returningIssueSearchPayloadwhosenodesexpose the same relation objects (state,assignee,team) asIssue, soISSUE_LIST_FIELDSworks unchanged. I therefore implemented withsearchIssues— same ranked Linear-app search, same composable filter, but not built on a field Linear has scheduled for removal. If maintainers prefer literalissueSearch(query:)despite the deprecation, it is a two-line swap infetchIssues.Edge case worth noting (works, but by design of two round trips):
--search x --assignee mefirst resolves the viewer (fetchViewer) and then composesassignee: { email: { eq: ... } }into thesearchIssuesfilter — covered by a test.skills/linear-axi/SKILL.mdis generated fromTOP_HELP(which does not enumerate per-command flags), so regeneration produces no diff;build:skill -- --checkpasses.Behavior demo (real output)
Before (main):
After (this branch):
The after case proves the flag is accepted and the GraphQL request is attempted (the fake key is rejected by Linear with 401). Query shape is asserted exactly in unit tests. Updated help:
README already documents
--searchin the issues filters line, so with this change the docs and CLI no longer drift (no README edit needed).Verification (real output)
41 → 49 tests (8 new).
pnpm run format:checkremains RED exactly as on main (18 pre-existing files flagged by prettier; CI does not run it) — no newly flagged files;test/issues-search.test.tspassesprettier --check.CI caveat
This org is known to have Actions quota-blocked: some jobs are rejected pre-execution with a billing/spending-limit annotation, which surfaces as a failed check. If a check is red here, please inspect the run's billing annotation before assuming this change broke it — local output above is the source of truth. The job was not retried.
Identity note
This PR was opened by an automated agent dispatch authenticated as
seraph-pixelperfect, for human review. It was not self-approved; merge is a human decision.