Repository navigation
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
Priority: ➖ Normal — Impact reflects medium issue severity. Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to Jira preset filters now use status categories for open and done issue selection, with tests covering each preset. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
No CI has run on this PR.
Fixes #16808. |
ELI5
Orca's Jira tab has four preset filters (Assigned, Reported, Done, All Open). They decide whether an issue is finished by looking at Jira's
resolutionfield. That field is not filled in automatically - a Jira admin has to add a "Set Issue Resolution" post-function to the workflow, and plenty of projects never do. In those projects every issue keeps an empty resolution forever, so Orca thinks finished work is still open, and the Done tab comes up almost empty. This switches the presets tostatusCategory, which Jira always fills in no matter how the workflow is set up.What Changed
filterToJql()insrc/main/jira/jira-issue-search.tsnow builds all four preset queries fromstatusCategoryinstead ofresolution:assignee = currentUser() AND resolution = Unresolvedassignee = currentUser() AND statusCategory != Donereporter = currentUser() AND resolution = Unresolvedreporter = currentUser() AND statusCategory != Doneassignee = currentUser() AND resolution IS NOT EMPTYassignee = currentUser() AND statusCategory = Doneresolution = UnresolvedstatusCategory != DoneORDER BY updated DESC, the function signature, and every other code path are unchanged. The function is now exported so it can be unit tested. The Jira tab's raw JQL search box is untouched.Added
src/main/jira/jira-issue-search.test.ts.Why
This is a correctness bug, not a preference.
resolutionis a Jira system field, but nothing populates it on its own. It is set by a workflow post-function on the transition into a done status. Company-managed projects created without that post-function leaveresolutionnull on every issue, permanently. Team-managed projects generally look fine because they fill it on the move into the Done category - which is exactly what makes this easy to miss.Two things then go wrong:
resolution = Unresolvedis effectively an alias forresolution IS EMPTY. A null resolution matches it, so completed issues are returned as open by Assigned, Reported, and All Open.resolution IS NOT EMPTYmatches nothing, so Done comes up empty.There is a mirror-image failure in the other direction: if a workflow reopens an issue without clearing resolution, that genuinely open issue vanishes from Assigned.
Measured on one project of a Jira Cloud site whose Done transition has no resolution post-function (counts from the REST API):
The Done preset misses 1,651 of 1,782 completed issues, and those same issues show up under Assigned as if they were still open.
statusCategoryhas none of this coupling. Every status maps to exactly one of To Do, In Progress, or Done, and that mapping is a property of the status itself rather than of the workflow. It is long-standing JQL on both Cloud and Server/DC; I verified the queries against Cloud, and theauthType === 'server'branch in this file selects a different search endpoint rather than different query semantics, so it is unaffected either way.This also lines up with the repository's provider-neutral guidance in CONTRIBUTING: keying generic behavior on
resolutionassumes a per-organization workflow configuration, and silently misbehaves for organizations that do not share it.On the
DoneliteralstatusCategory = Doneuses an English literal, so I checked whether it survives a non-English Jira instance rather than assuming it. On a Jira Cloud site running a Korean locale, where the category's display name renders as완료:The English literal is the form JQL accepts; the localized display name is the one that fails. So the readable literal is also the portable one, and there is no reason to reach for the numeric category ID.
Linked Issue
Fixes #16808
Visual Proof
Both shots are the Assigned preset's query, run against a project whose Done transition has no resolution post-function. Issue titles and assignee names are blurred; the Key and Status columns are what matter.
Before -
resolution = Unresolved, the current preset query. Every row carries a "Done" status badge, in a filter that is supposed to list open work. The result header readsDone 50/50 shown.After -
statusCategory != Done, this PR's query.0 shown, empty state. That is the correct answer: I have no open issues assigned to me in that project.Two notes on how these were produced:
filterToJql()returns. The rendered result is what the preset produces.project = ...clause to both queries to isolate the affected project. The presets themselves are site-wide, and without that clause the 50-row cap fills up with issues from projects that do populate resolution, which hides the bug rather than showing it.For the Done preset the same site gives 115 issues before and 1,160 after, but that pair does not make a useful screenshot: both sides hit the 50-row cap and look identical. The counts are in the Why section above.
Testing
New unit tests in
src/main/jira/jira-issue-search.test.tscover all four presets, assert that no preset JQL containsresolution, and assert theORDER BY updated DESCsuffix is preserved.I checked that they actually catch this regression rather than just passing: reverting
filterToJql()to the old implementation fails 5 of the 6, and restoring the fix passes all 6.Verified locally on Linux (Node 24, matching
engines):pnpm lint,pnpm typecheck,pnpm build- cleanpnpm test- one failure, which predates this change and is unrelated to it (details below).src/main/jirais fully green: 8 files, 89 testscheck:code-quality:changed,check:react-doctor:changed,check:zustand-selector-fanout, the reliability / max-lines / runtime-electron ratchets, and the root-directory guard - all cleanOn that one failure: my first full run showed 15 failures across 14 files, but 13 of those files were my environment rather than the code. Twelve
src/main/browser/*.electron.test.tsfiles needxvfb-run, which I had not installed, andtests/e2e/cross-version-wire/cross-version-browser-placement.unit.test.tsneeds tagv1.4.184present locally, which my--depth 50clone lacked. After installing xvfb and fetching the tag, 13 of the 14 pass.The one that remains is
src/shared/runtime-client-export-parity.test.ts, which hard-codes the expected export list ofruntime-types.TERMINAL_PTY_DEGRADATION_CAPABILITYandTERMINAL_UNAVAILABLE_ERROR_CODEwere added in 5631aa0 (#16398) without updating that list. It reproduces on a clean checkout ofmainwith nothing applied, so I left it alone rather than widen this PR's scope. Happy to file it separately.The behavior change was also exercised against a live Jira Cloud site by running the before and after JQL through the REST API; the counts above come from that site.
AI Disclosure
Written with Claude Code (Claude Opus 5). The JQL claims here were checked against a live Jira Cloud instance rather than taken from the model.
Review
filterToJql()produces a JQL string that is sent to the Jira REST API over HTTP by the existing caller. No local filesystem or process assumptions are added or removed.statusCategoryis supported on Jira Cloud and Server/DC alike, so the existingauthType === 'server'search-path branch in this file keeps working unchanged. No other integration or git provider touches this function.maxResults, same fields.statusCategoryis an indexed system field likeresolution.Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)Author
X: @chung297