Skip to content

feat: add issues --search full-text search - #37

Closed
seraph-pixelperfect wants to merge 1 commit into
mainfrom
feat/issues-search
Closed

seraph-pixelperfect wants to merge 1 commit into
mainfrom
feat/issues-search

Conversation

@seraph-pixelperfect

Copy link
Copy Markdown
Collaborator

Closes #17

What changed

  • src/commands/issues.ts: --search <text> added to KNOWN_FLAGS and ISSUES_HELP (usage line, flag entry, example). A missing or blank --search value 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: IssueListFilter gains search?: string. When set, fetchIssues issues a searchIssues(term: $term, filter: { ... }, first: $first) query instead of issues(...), composing the exact same IssueFilter and reusing ISSUE_LIST_FIELDS. Without --search, the existing issues query (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, plain issues still used without search, KNOWN_FLAGS acceptance + rendering, --assignee me viewer 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:

  • issueSearch does accept filter: IssueFilter + first: Int (plus after, before, includeArchived, last, orderBy) — so the issue's or/icontains fallback is not needed.
  • However, two facts differ from the issue text:
    1. Its search-term argument is named query, not term (query issueSearch($after: String, $before: String, $filter: IssueFilter, $first: Int, $includeArchived: Boolean, $last: Int, $orderBy: PaginationOrderBy, $query: String)).
    2. The field is marked deprecated in the schema: "[DEPRECATED] Search issues. This endpoint is deprecated and will be removed in the future – use searchIssues instead."

searchIssues is the recommended replacement and accepts everything we need: searchIssues(term: String!, filter: IssueFilter, first: Int, ...), returning IssueSearchPayload whose nodes expose the same relation objects (state, assignee, team) as Issue, so ISSUE_LIST_FIELDS works unchanged. I therefore implemented with searchIssues — same ranked Linear-app search, same composable filter, but not built on a field Linear has scheduled for removal. If maintainers prefer literal issueSearch(query:) despite the deprecation, it is a two-line swap in fetchIssues.

Edge case worth noting (works, but by design of two round trips): --search x --assignee me first resolves the viewer (fetchViewer) and then composes assignee: { email: { eq: ... } } into the searchIssues filter — covered by a test.

skills/linear-axi/SKILL.md is generated from TOP_HELP (which does not enumerate per-command flags), so regeneration produces no diff; build:skill -- --check passes.

Behavior demo (real output)

Before (main):

$ pnpm exec tsx bin/linear-axi.ts issues --search x --key lin_api_fake
error: unknown flag --search
code: VALIDATION_ERROR
help[1]: "valid flags: --team, --state, --assignee, --label, --limit (--help always allowed)"
exit=2

After (this branch):

$ pnpm exec tsx bin/linear-axi.ts issues --search x --key lin_api_fake
error: Linear auth required — set LINEAR_API_KEY or pass --key <key>
code: AUTH_REQUIRED
help[2]: "Create a personal API key at https://linear.app/settings/api",Then export LINEAR_API_KEY=<key> or run commands with --key <key>
exit=1

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:

$ pnpm exec tsx bin/linear-axi.ts issues --help
usage: linear-axi issues [--team <KEY>] [--state <type>] [--assignee <name|me>] [--label <name>] [--search <text>] [--limit <n>]
List Linear issues, most recently updated first (relevance-ranked when --search is given).

flags:
  --team <KEY>       filter by team key (e.g. LIN)
  --state <type>     workflow state type: backlog, unstarted, started, completed, canceled, triage
  --assignee <name>  "me" for yourself, or a user name
  --label <name>     filter by label name (repeatable)
  --search <text>    full-text search (same ranking as Linear's app search); composable with the filters above
  --limit <n>        max issues to return (default 25, capped at 50)

examples:
  linear-axi issues
  linear-axi issues --assignee me --state started
  linear-axi issues --team LIN --label bug
  linear-axi issues --search "onboarding" --team LIN --state started

README already documents --search in the issues filters line, so with this change the docs and CLI no longer drift (no README edit needed).

Verification (real output)

$ pnpm build
$ tsc
exit=0

$ pnpm lint
$ eslint .
exit=0

$ pnpm run build:skill -- --check
skills/linear-axi/SKILL.md is up to date.
exit=0

$ pnpm test
 ✓ test/config.test.ts (12 tests) 6ms
 ✓ test/issues-search.test.ts (8 tests) 5ms

 Test Files  7 passed (7)
      Tests  49 passed (49)
   Duration  252ms

41 → 49 tests (8 new). pnpm run format:check remains 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.ts passes prettier --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.

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.
@ghostinprod-pixelperfect

Copy link
Copy Markdown
Collaborator

Superseded by merged rc/0.1 PR #51 (commit 694a564), which consolidated this read/discovery stack with validation and review fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add issues --search full-text search

2 participants