-
Notifications
You must be signed in to change notification settings - Fork 0
fix: migrate JQL search to /rest/api/3/search/jql #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -7,17 +7,18 @@ import { createJiraClient } from '../jira-client'; | |||||
| import { logDebugEvent } from '../debug-logger'; | ||||||
|
|
||||||
| export const jiraSearchIssuesTool = tool({ | ||||||
| description: 'Search Jira issues using JQL (Jira Query Language). Use text ~ "keyword" for text search, status = "In Progress" for status filter, project = "PROJ" for project filter. Combine with AND/OR.', | ||||||
| description: 'Search Jira issues using JQL (Jira Query Language). Use text ~ "keyword" for text search, status = "In Progress" for status filter, project = "PROJ" for project filter. Combine with AND/OR. Results are paged — pass the returned nextPageToken to fetch the following page.', | ||||||
|
|
||||||
| args: { | ||||||
| jql: tool.schema.string().describe('JQL query (e.g. \'text ~ "footer" AND status = "Code Review" ORDER BY updated DESC\')'), | ||||||
| maxResults: tool.schema.number().optional().describe('Max results (default: 10)'), | ||||||
| maxResults: tool.schema.number().optional().describe('Max results per page (default: 10, max: 5000)'), | ||||||
| nextPageToken: tool.schema.string().optional().describe('Page token returned by a previous search, to fetch the next page'), | ||||||
| }, | ||||||
|
|
||||||
| async execute(args, ctx) { | ||||||
| const { jql, maxResults } = args; | ||||||
| const { jql, maxResults, nextPageToken } = args; | ||||||
|
|
||||||
| logDebugEvent('jira_search_issues.start', { jql, maxResults }); | ||||||
| logDebugEvent('jira_search_issues.start', { jql, maxResults, paged: Boolean(nextPageToken) }); | ||||||
|
|
||||||
| try { | ||||||
| const config = loadConfig(ctx.directory); | ||||||
|
|
@@ -26,14 +27,14 @@ export const jiraSearchIssuesTool = tool({ | |||||
| const client = createJiraClient(config); | ||||||
| if (!client) return 'Jira client not configured.'; | ||||||
|
|
||||||
| const result = await client.searchIssues(jql, maxResults || 10); | ||||||
| const result = await client.searchIssues(jql, maxResults || 10, { nextPageToken }); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Preserve an explicit zero page size for client clamping.
🤖 Prompt for AI AgentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: When the tool receives Prompt for AI agents
Suggested change
|
||||||
|
|
||||||
| if (typeof result === 'object' && 'error' in result && result.error) { | ||||||
| if ('error' in result) { | ||||||
| return `Search failed: ${result.message}`; | ||||||
| } | ||||||
|
|
||||||
| const issues = result as Array<any>; | ||||||
| if (!issues || issues.length === 0) { | ||||||
| const { issues, isLast, nextPageToken: nextToken } = result; | ||||||
| if (issues.length === 0) { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: When Jira returns an empty non-final page, this early return drops Prompt for AI agents
Suggested change
|
||||||
| return `No issues found for JQL: ${jql}`; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -43,8 +44,12 @@ export const jiraSearchIssuesTool = tool({ | |||||
| const assignee = issue.fields?.assignee?.displayName || 'unassigned'; | ||||||
| lines.push(` - ${issue.key}: ${issue.fields?.summary || '(no summary)'} [${status}] (${assignee})`); | ||||||
| } | ||||||
| // The API reports no total — only whether another page exists. | ||||||
| if (!isLast && nextToken) { | ||||||
| lines.push(`\nMore results available — nextPageToken: ${nextToken}`); | ||||||
| } | ||||||
|
|
||||||
| logDebugEvent('jira_search_issues.success', { jql, count: issues.length }); | ||||||
| logDebugEvent('jira_search_issues.success', { jql, count: issues.length, isLast }); | ||||||
| return lines.join('\n'); | ||||||
| } catch (err) { | ||||||
| const msg = err instanceof Error ? err.message : String(err); | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -96,6 +96,19 @@ export interface Transition { | |||||
| name: string; | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Result of a JQL search via POST /rest/api/3/search/jql. | ||||||
| * | ||||||
| * The enhanced-search endpoint pages with an opaque cursor instead of | ||||||
| * `startAt`, and returns no `total` — use the approximate-count endpoint | ||||||
| * if a count is needed. | ||||||
| */ | ||||||
| export interface SearchResult { | ||||||
| issues: JiraIssue[]; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Do not declare caller-selected fields as complete
🤖 Prompt for AI AgentsThere was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: When callers provide a partial Prompt for AI agents
Suggested change
|
||||||
| nextPageToken?: string; | ||||||
| isLast: boolean; | ||||||
| } | ||||||
|
|
||||||
| export interface CreatedIssue { | ||||||
| id: string; | ||||||
| key: string; | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: The package is now version
0.4.0, but plugin initialization still logs0.3.0. Update the initialization version so diagnostics identify the released version correctly.Prompt for AI agents