Support Jira Server and Data Center sites#7242
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds deployment-aware Jira support for Cloud and Server/Data Center. Shared Jira types now distinguish deployment type, auth mode, and user identifiers. Main-process Jira logic is split into request, storage, identity, routing, search, metadata, comments, and client modules with server/cloud branching. IPC, RPC, preload, renderer store/runtime, and UI layers now accept cloud or server connect payloads, and assignee updates use Related PRs: None specified 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/renderer/src/components/TaskPage.tsx (1)
5544-5544: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winGuard page-level UI while the Jira connect dialog is open.
jiraConnectOpenis not included in the Tasks tour/Escape-modal guards. Move this state above those guards and include!jiraConnectOpen/jiraConnectOpenchecks so opening the connect dialog does not let page-level tour or Escape handling interfere with the modal.Also applies to: 12367-12367
src/main/ipc/jira.ts (1)
119-132: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReject mixed assignee IDs.
updateIssuesilently prefersassigneeUserIdwhen both fields are present, so a mixed payload can update the wrong assignee on Cloud/Server. Reject the combination here or normalize it to a single field first.
🧹 Nitpick comments (9)
src/renderer/src/components/jira-create-field-payload.test.ts (1)
1-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for array/allowedValues/number branches.
Tests only cover the textarea server-vs-cloud path in
buildJiraCreateFieldValue. The array-split, allowedValues option-payload, and number-parsing branches injira-create-field-payload.ts(lines 47-65) are untested.src/shared/jira-types.ts (1)
137-163: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument why
deploymentTypeis optional only on the Cloud variant.
JiraCloudConnectArgs.deploymentTypeis optional while both Server variants require the literal. This is intentional (per the design doc, legacy renderer/runtime callers omitdeploymentTypeand are normalized to Cloud at the IPC/RPC/store boundary), but nothing here explains that, and it weakens exhaustiveness checks onJiraConnectArgsfor any code that switches ondeploymentTypewithout also handlingundefined.As per path instructions, "When writing or modifying code driven by a design doc or non-obvious constraint, add a comment explaining why the code behaves the way it does."
💬 Suggested comment
export type JiraCloudConnectArgs = { + // Optional for legacy callers that predate Server/DC support; normalized + // to 'cloud' at the IPC/RPC/store boundary before reaching the client. deploymentType?: 'cloud' siteUrl: stringSource: Path instructions
src/renderer/src/i18n/locales/en.json (1)
7557-7558: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLocale key naming deviates from hash-based convention for settings strings.
New Jira Server/Data Center keys (
jiraServerKeyword,jiraDataCenterKeyword,jiraCloudServerCredentials,jiraCloudServerRemoteCredentialCopy,jiraCloudServerLocalCredentialCopy,jiraCloudServerIssueDescription,connectedJiraCredentialStorage,cloudServerDescription,deploymentType, etc.) use descriptive names instead of theSHA1(path+text)hash convention used for most existing keys in these same objects.Not blocking — the file already mixes both styles (e.g.
disconnect_all,account_scope_prefix) — but worth confirming this is intentional rather than a missedpnpm bootstrap:locale-catalogrun, since the convention was called out specifically for settings-component locale strings.Based on learnings, "when localizing user-facing strings inside settings components (e.g.,
src/renderer/src/components/settings/*.tsx), use hash-based locale keys withtranslate('auto.components.<Dir>.<ComponentFile>.<10-char-hash>', 'Default English text')... then runpnpm bootstrap:locale-catalogso translations propagate toes/ja/ko/zh."Also applies to: 7581-7582, 8415-8419, 12147-12161
Source: Learnings
src/main/ipc/jira.ts (2)
58-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider extracting per-deployment normalization to reduce complexity.
normalizeConnectArgshandles three branches (cloud, server-basic, server-bearer) inline with repeatedhasOnlyKeys+normalizeRequiredString+ ternary patterns. Extracting small helpers (e.g.,normalizeCloudConnectArgs,normalizeServerBasicConnectArgs,normalizeServerBearerConnectArgs) would improve readability and make each branch independently testable.Source: Linters/SAST tools
119-139: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate nullable-string validation pattern.
The
undefined/null/non-string checks forassigneeUserId,assigneeAccountId, andpriorityIdrepeat the same three-line pattern. A small helper likeisNullableString(value)would remove the duplication and make it easy to add future nullable fields consistently.♻️ Proposed helper
+function isNullableString(value: unknown): boolean { + return value === undefined || value === null || typeof value === 'string' +} + function normalizeIssueUpdate(value: unknown): JiraIssueUpdate | null { ... - if ( - input.assigneeUserId !== undefined && - input.assigneeUserId !== null && - typeof input.assigneeUserId !== 'string' - ) { - return null - } + if (!isNullableString(input.assigneeUserId)) { + return null + }src/main/ipc/jira.test.ts (1)
74-163: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winGood coverage of the new normalization paths; consider a few additional cases.
Tests correctly cover server basic/bearer connect trimming and the mixed-payload rejection, plus assigneeUserId acceptance/rejection. Consider adding a case for a cloud connect payload (with/without
deploymentType) and an explicit invaliddeploymentTypevalue to fully lock innormalizeConnectArgsbranch coverage.src/main/runtime/rpc/methods/jira.ts (1)
18-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
.strict()is deprecated in Zod 4 in favor ofz.strictObject().Per Zod's v4 migration guide,
.strict()"are still available for backwards compatibility... [but] are considered legacy," withz.strictObject()/z.looseObject()as the preferred replacement. Since the project is on zod@4.4.3, consider migrating these three schemas for consistency with idiomatic Zod 4 usage (purely cosmetic — behavior is unchanged).♻️ Example migration
-const ServerBasicConnect = z - .object({ - deploymentType: z.literal('server'), - authMode: z.literal('basic'), - siteUrl: requiredString('Site URL is required'), - username: requiredString('Username is required'), - passwordOrToken: requiredString('Password or token is required') - }) - .strict() +const ServerBasicConnect = z.strictObject({ + deploymentType: z.literal('server'), + authMode: z.literal('basic'), + siteUrl: requiredString('Site URL is required'), + username: requiredString('Username is required'), + passwordOrToken: requiredString('Password or token is required') +})src/main/jira/jira-user-identity.ts (1)
3-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDuplicate
asRecord/asString/JiraRecordprimitives.These are identical to the exported versions in
issue-mappers.ts(Lines 29, 44-50 there). Direct reuse isn't possible without a cycle sinceissue-mappers.tsalready importsmapJiraUserfrom this file. Consider extracting these primitives into a small shared module (e.g.jira-primitives.ts) that both files import.src/main/jira/site-storage.ts (1)
83-102: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDuplicate URL credential-stripping logic vs.
client.ts'snormalizeJiraSiteUrl.This function reimplements the same protocol/username/password/search/hash stripping as
normalizeJiraSiteUrlinclient.ts(Lines 54-65), differing only in the try/catch wrapper. Since both exist specifically to prevent credential leakage into site metadata, having two independent copies risks future divergence reintroducing that leak if only one is updated. Extract the core stripping logic into a shared helper (e.g. in a smalljira-url.tsmodule importable by both, sincesite-storage.tscan't import fromclient.tswithout a cycle) and have each call site apply its own throw-vs-fallback behavior around it.♻️ Sketch of shared helper
+// jira-url.ts +export function stripJiraUrlCredentials(url: URL): void { + url.username = '' + url.password = '' + url.pathname = url.pathname.replace(/\/+$/, '') + url.search = '' + url.hash = '' +}- try { - const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}` - const url = new URL(withProtocol) - url.username = '' - url.password = '' - url.pathname = url.pathname.replace(/\/+$/, '') - url.search = '' - url.hash = '' - return url.toString().replace(/\/$/, '') - } catch { - return trimmed - } + try { + const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}` + const url = new URL(withProtocol) + stripJiraUrlCredentials(url) + return url.toString().replace(/\/$/, '') + } catch { + return trimmed + }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 4616f886-2b82-40d8-9ea5-8d261542a4fb
📒 Files selected for processing (48)
docs/reference/README.mddocs/reference/jira-server-support.mdsrc/main/ipc/jira.test.tssrc/main/ipc/jira.tssrc/main/jira/auth-headers.tssrc/main/jira/client.test.tssrc/main/jira/client.tssrc/main/jira/issue-comments.tssrc/main/jira/issue-mappers.tssrc/main/jira/issue-metadata.tssrc/main/jira/issue-page-fetcher.tssrc/main/jira/issue-rest-routing.tssrc/main/jira/issue-search.tssrc/main/jira/issues.test.tssrc/main/jira/issues.tssrc/main/jira/jira-request.tssrc/main/jira/jira-user-identity.tssrc/main/jira/site-storage.tssrc/main/runtime/rpc/methods/jira.test.tssrc/main/runtime/rpc/methods/jira.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/JiraIssueWorkspace.tsxsrc/renderer/src/components/TaskPage.tsxsrc/renderer/src/components/feature-interaction-writer-boundaries.test.tssrc/renderer/src/components/jira-connect-dialog.test.tsxsrc/renderer/src/components/jira-connect-dialog.tsxsrc/renderer/src/components/jira-create-field-payload.test.tssrc/renderer/src/components/jira-create-field-payload.tssrc/renderer/src/components/jira-server-auth-fields.tsxsrc/renderer/src/components/right-sidebar/pr-comment-presentation.test.tssrc/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsxsrc/renderer/src/components/settings/integrations-search.tssrc/renderer/src/components/settings/jira-integration-card.test.tsxsrc/renderer/src/components/settings/jira-integration-card.tsxsrc/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsxsrc/renderer/src/components/sidebar/SidebarToolbar.test.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/runtime/runtime-jira-client.test.tssrc/renderer/src/runtime/runtime-jira-client.tssrc/renderer/src/store/slices/jira.tssrc/renderer/src/test/memory-storage.tssrc/shared/jira-types.tssrc/shared/types.ts
20233a6 to
4d11fce
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/main/jira/jira-site-url.ts (1)
1-1: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winConsider restricting
PROTOCOL_PATTERNtohttp(s).Any scheme matching
^[a-z][a-z0-9+.-]*:\/\//iis accepted as-is (e.g.file://,ftp://), so a malformed or accidental non-HTTP site URL would be normalized and stored rather than rejected here. Since this is the single normalization point feeding both storage and (per the PR summary) request routing, validating the scheme ishttp/httpswould fail fast with a clearer error instead of surfacing confusing failures downstream.♻️ Proposed tightening of allowed protocols
-const PROTOCOL_PATTERN = /^[a-z][a-z0-9+.-]*:\/\//i +const PROTOCOL_PATTERN = /^https?:\/\//iAlso applies to: 13-19
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1c3eb053-a5dd-48c3-9bf7-d3ef03e43e58
📒 Files selected for processing (51)
docs/reference/README.mddocs/reference/jira-server-support.mdsrc/main/ipc/jira-connect-args-normalization.tssrc/main/ipc/jira.test.tssrc/main/ipc/jira.tssrc/main/jira/auth-headers.tssrc/main/jira/client.test.tssrc/main/jira/client.tssrc/main/jira/issue-comments.tssrc/main/jira/issue-mappers.tssrc/main/jira/issue-metadata.tssrc/main/jira/issue-page-fetcher.tssrc/main/jira/issue-rest-routing.tssrc/main/jira/issue-search.tssrc/main/jira/issues.test.tssrc/main/jira/issues.tssrc/main/jira/jira-record-primitives.tssrc/main/jira/jira-request.tssrc/main/jira/jira-site-url.tssrc/main/jira/jira-user-identity.tssrc/main/jira/site-storage.tssrc/main/runtime/rpc/methods/jira.test.tssrc/main/runtime/rpc/methods/jira.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/JiraIssueWorkspace.tsxsrc/renderer/src/components/TaskPage.tsxsrc/renderer/src/components/feature-interaction-writer-boundaries.test.tssrc/renderer/src/components/jira-connect-dialog.test.tsxsrc/renderer/src/components/jira-connect-dialog.tsxsrc/renderer/src/components/jira-create-field-payload.test.tssrc/renderer/src/components/jira-create-field-payload.tssrc/renderer/src/components/jira-server-auth-fields.tsxsrc/renderer/src/components/right-sidebar/pr-comment-presentation.test.tssrc/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsxsrc/renderer/src/components/settings/integrations-search.tssrc/renderer/src/components/settings/jira-integration-card.test.tsxsrc/renderer/src/components/settings/jira-integration-card.tsxsrc/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsxsrc/renderer/src/components/sidebar/SidebarToolbar.test.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/runtime/runtime-jira-client.test.tssrc/renderer/src/runtime/runtime-jira-client.tssrc/renderer/src/store/slices/jira.tssrc/renderer/src/test/memory-storage.tssrc/shared/jira-types.tssrc/shared/types.ts
✅ Files skipped from review due to trivial changes (4)
- docs/reference/README.md
- src/shared/types.ts
- src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsx
- src/renderer/src/components/feature-interaction-writer-boundaries.test.ts
🚧 Files skipped from review as they are similar to previous changes (39)
- src/renderer/src/components/settings/integrations-search.ts
- src/main/jira/auth-headers.ts
- src/renderer/src/components/sidebar/SidebarToolbar.test.tsx
- src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts
- src/main/jira/issue-rest-routing.ts
- src/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsx
- src/renderer/src/components/JiraIssueWorkspace.tsx
- src/renderer/src/components/jira-connect-dialog.test.tsx
- src/preload/api-types.ts
- src/main/jira/client.test.ts
- src/main/jira/issue-comments.ts
- src/renderer/src/components/settings/jira-integration-card.tsx
- src/main/jira/issue-page-fetcher.ts
- src/preload/index.ts
- src/main/runtime/rpc/methods/jira.test.ts
- src/renderer/src/components/jira-connect-dialog.tsx
- src/renderer/src/runtime/runtime-jira-client.ts
- src/main/jira/jira-user-identity.ts
- src/main/runtime/rpc/methods/jira.ts
- src/renderer/src/test/memory-storage.ts
- src/main/ipc/jira.ts
- src/renderer/src/components/jira-create-field-payload.ts
- src/renderer/src/components/settings/jira-integration-card.test.tsx
- src/main/jira/issues.test.ts
- src/renderer/src/store/slices/jira.ts
- src/main/jira/issue-search.ts
- src/main/jira/issues.ts
- src/renderer/src/components/jira-server-auth-fields.tsx
- src/renderer/src/i18n/locales/ja.json
- src/main/jira/issue-metadata.ts
- src/shared/jira-types.ts
- src/main/jira/client.ts
- src/main/jira/jira-request.ts
- src/renderer/src/i18n/locales/ko.json
- src/main/jira/site-storage.ts
- src/renderer/src/runtime/runtime-jira-client.test.ts
- src/main/jira/issue-mappers.ts
- src/renderer/src/i18n/locales/es.json
- src/renderer/src/components/TaskPage.tsx
4d11fce to
6cb3bbb
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/ipc/jira.ts (1)
82-90: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRedundant assignee validation in
normalizeIssueUpdate.
getIssueUpdateValidationError(lines 54-69) already validatesassigneeUserId/assigneeAccountIdtypes and mixed-identifier usage, and is called beforenormalizeIssueUpdateat the only call site (Line 191-195). These three checks can never fail here anymore, making them dead code.♻️ Proposed cleanup
- if (!isNullableString(input.assigneeUserId)) { - return null - } - if (!isNullableString(input.assigneeAccountId)) { - return null - } - if (input.assigneeUserId !== undefined && input.assigneeAccountId !== undefined) { - return null - } if (!isNullableString(input.priorityId)) { return null }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b760db17-58dc-4c31-b78f-a59a02e58cbf
📒 Files selected for processing (51)
docs/reference/README.mddocs/reference/jira-server-support.mdsrc/main/ipc/jira-connect-args-normalization.tssrc/main/ipc/jira.test.tssrc/main/ipc/jira.tssrc/main/jira/auth-headers.tssrc/main/jira/client.test.tssrc/main/jira/client.tssrc/main/jira/issue-comments.tssrc/main/jira/issue-mappers.tssrc/main/jira/issue-metadata.tssrc/main/jira/issue-page-fetcher.tssrc/main/jira/issue-rest-routing.tssrc/main/jira/issue-search.tssrc/main/jira/issues.test.tssrc/main/jira/issues.tssrc/main/jira/jira-record-primitives.tssrc/main/jira/jira-request.tssrc/main/jira/jira-site-url.tssrc/main/jira/jira-user-identity.tssrc/main/jira/site-storage.tssrc/main/runtime/rpc/methods/jira.test.tssrc/main/runtime/rpc/methods/jira.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/JiraIssueWorkspace.tsxsrc/renderer/src/components/TaskPage.tsxsrc/renderer/src/components/feature-interaction-writer-boundaries.test.tssrc/renderer/src/components/jira-connect-dialog.test.tsxsrc/renderer/src/components/jira-connect-dialog.tsxsrc/renderer/src/components/jira-create-field-payload.test.tssrc/renderer/src/components/jira-create-field-payload.tssrc/renderer/src/components/jira-server-auth-fields.tsxsrc/renderer/src/components/right-sidebar/pr-comment-presentation.test.tssrc/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsxsrc/renderer/src/components/settings/integrations-search.tssrc/renderer/src/components/settings/jira-integration-card.test.tsxsrc/renderer/src/components/settings/jira-integration-card.tsxsrc/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsxsrc/renderer/src/components/sidebar/SidebarToolbar.test.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/runtime/runtime-jira-client.test.tssrc/renderer/src/runtime/runtime-jira-client.tssrc/renderer/src/store/slices/jira.tssrc/renderer/src/test/memory-storage.tssrc/shared/jira-types.tssrc/shared/types.ts
✅ Files skipped from review due to trivial changes (3)
- docs/reference/README.md
- src/shared/types.ts
- src/renderer/src/components/settings/integrations-search.ts
🚧 Files skipped from review as they are similar to previous changes (43)
- src/main/jira/issue-rest-routing.ts
- src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts
- src/main/jira/jira-record-primitives.ts
- src/preload/api-types.ts
- src/main/jira/auth-headers.ts
- src/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsx
- src/preload/index.ts
- src/renderer/src/components/JiraIssueWorkspace.tsx
- src/renderer/src/components/jira-server-auth-fields.tsx
- src/renderer/src/runtime/runtime-jira-client.test.ts
- src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsx
- src/main/runtime/rpc/methods/jira.test.ts
- src/renderer/src/test/memory-storage.ts
- src/renderer/src/components/jira-connect-dialog.test.tsx
- src/renderer/src/components/jira-create-field-payload.test.ts
- src/main/ipc/jira-connect-args-normalization.ts
- src/renderer/src/runtime/runtime-jira-client.ts
- src/renderer/src/components/sidebar/SidebarToolbar.test.tsx
- src/main/jira/jira-user-identity.ts
- src/main/jira/issue-comments.ts
- src/renderer/src/components/settings/jira-integration-card.tsx
- src/renderer/src/components/feature-interaction-writer-boundaries.test.ts
- src/main/jira/issue-page-fetcher.ts
- src/main/jira/issue-metadata.ts
- src/main/jira/issues.test.ts
- src/renderer/src/store/slices/jira.ts
- src/renderer/src/i18n/locales/ja.json
- src/main/jira/jira-request.ts
- src/main/jira/issue-mappers.ts
- src/renderer/src/components/settings/jira-integration-card.test.tsx
- src/main/jira/issue-search.ts
- src/main/runtime/rpc/methods/jira.ts
- src/renderer/src/components/jira-create-field-payload.ts
- src/renderer/src/i18n/locales/zh.json
- src/shared/jira-types.ts
- src/renderer/src/i18n/locales/es.json
- src/main/jira/issues.ts
- src/renderer/src/i18n/locales/en.json
- src/main/jira/client.ts
- src/renderer/src/i18n/locales/ko.json
- src/main/jira/site-storage.ts
- src/renderer/src/components/TaskPage.tsx
- src/renderer/src/components/jira-connect-dialog.tsx
6cb3bbb to
b441c7a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 6f7869fe-e1e1-4142-a3fb-33bbc9da5219
📒 Files selected for processing (51)
docs/reference/README.mddocs/reference/jira-server-support.mdsrc/main/ipc/jira-connect-args-normalization.tssrc/main/ipc/jira.test.tssrc/main/ipc/jira.tssrc/main/jira/auth-headers.tssrc/main/jira/client.test.tssrc/main/jira/client.tssrc/main/jira/issue-comments.tssrc/main/jira/issue-mappers.tssrc/main/jira/issue-metadata.tssrc/main/jira/issue-page-fetcher.tssrc/main/jira/issue-rest-routing.tssrc/main/jira/issue-search.tssrc/main/jira/issues.test.tssrc/main/jira/issues.tssrc/main/jira/jira-record-primitives.tssrc/main/jira/jira-request.tssrc/main/jira/jira-site-url.tssrc/main/jira/jira-user-identity.tssrc/main/jira/site-storage.tssrc/main/runtime/rpc/methods/jira.test.tssrc/main/runtime/rpc/methods/jira.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/JiraIssueWorkspace.tsxsrc/renderer/src/components/TaskPage.tsxsrc/renderer/src/components/feature-interaction-writer-boundaries.test.tssrc/renderer/src/components/jira-connect-dialog.test.tsxsrc/renderer/src/components/jira-connect-dialog.tsxsrc/renderer/src/components/jira-create-field-payload.test.tssrc/renderer/src/components/jira-create-field-payload.tssrc/renderer/src/components/jira-server-auth-fields.tsxsrc/renderer/src/components/right-sidebar/pr-comment-presentation.test.tssrc/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsxsrc/renderer/src/components/settings/integrations-search.tssrc/renderer/src/components/settings/jira-integration-card.test.tsxsrc/renderer/src/components/settings/jira-integration-card.tsxsrc/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsxsrc/renderer/src/components/sidebar/SidebarToolbar.test.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/runtime/runtime-jira-client.test.tssrc/renderer/src/runtime/runtime-jira-client.tssrc/renderer/src/store/slices/jira.tssrc/renderer/src/test/memory-storage.tssrc/shared/jira-types.tssrc/shared/types.ts
✅ Files skipped from review due to trivial changes (2)
- docs/reference/README.md
- src/renderer/src/i18n/locales/en.json
🚧 Files skipped from review as they are similar to previous changes (48)
- src/renderer/src/components/settings/integrations-search.ts
- src/shared/types.ts
- src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts
- src/main/jira/jira-record-primitives.ts
- src/preload/api-types.ts
- src/renderer/src/components/feature-interaction-writer-boundaries.test.ts
- src/main/ipc/jira-connect-args-normalization.ts
- src/main/jira/auth-headers.ts
- src/renderer/src/store/slices/jira.ts
- src/main/jira/issue-rest-routing.ts
- src/renderer/src/runtime/runtime-jira-client.test.ts
- src/main/jira/jira-site-url.ts
- src/renderer/src/components/JiraIssueWorkspace.tsx
- src/renderer/src/components/settings/jira-integration-card.test.tsx
- src/renderer/src/components/sidebar/SidebarToolbar.test.tsx
- src/renderer/src/components/jira-create-field-payload.ts
- src/renderer/src/components/jira-server-auth-fields.tsx
- src/renderer/src/components/jira-connect-dialog.test.tsx
- src/renderer/src/components/settings/jira-integration-card.tsx
- src/renderer/src/runtime/runtime-jira-client.ts
- src/main/jira/jira-user-identity.ts
- src/main/runtime/rpc/methods/jira.test.ts
- src/renderer/src/test/memory-storage.ts
- src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsx
- src/main/runtime/rpc/methods/jira.ts
- src/main/ipc/jira.ts
- src/renderer/src/i18n/locales/ja.json
- src/preload/index.ts
- src/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsx
- src/main/ipc/jira.test.ts
- src/shared/jira-types.ts
- src/main/jira/issue-search.ts
- src/main/jira/issue-comments.ts
- src/renderer/src/i18n/locales/es.json
- src/renderer/src/components/jira-connect-dialog.tsx
- src/main/jira/jira-request.ts
- src/main/jira/issue-metadata.ts
- src/main/jira/issues.ts
- src/main/jira/site-storage.ts
- src/renderer/src/i18n/locales/ko.json
- src/main/jira/client.test.ts
- src/renderer/src/components/jira-create-field-payload.test.ts
- src/main/jira/client.ts
- src/main/jira/issue-page-fetcher.ts
- src/main/jira/issue-mappers.ts
- src/main/jira/issues.test.ts
- src/renderer/src/i18n/locales/zh.json
- src/renderer/src/components/TaskPage.tsx
b441c7a to
dcca89f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 1134d454-867c-4de4-aa05-10e6301999ad
📒 Files selected for processing (51)
docs/reference/README.mddocs/reference/jira-server-support.mdsrc/main/ipc/jira-connect-args-normalization.tssrc/main/ipc/jira.test.tssrc/main/ipc/jira.tssrc/main/jira/auth-headers.tssrc/main/jira/client.test.tssrc/main/jira/client.tssrc/main/jira/issue-comments.tssrc/main/jira/issue-mappers.tssrc/main/jira/issue-metadata.tssrc/main/jira/issue-page-fetcher.tssrc/main/jira/issue-rest-routing.tssrc/main/jira/issue-search.tssrc/main/jira/issues.test.tssrc/main/jira/issues.tssrc/main/jira/jira-record-primitives.tssrc/main/jira/jira-request.tssrc/main/jira/jira-site-url.tssrc/main/jira/jira-user-identity.tssrc/main/jira/site-storage.tssrc/main/runtime/rpc/methods/jira.test.tssrc/main/runtime/rpc/methods/jira.tssrc/preload/api-types.tssrc/preload/index.tssrc/renderer/src/components/JiraIssueWorkspace.tsxsrc/renderer/src/components/TaskPage.tsxsrc/renderer/src/components/feature-interaction-writer-boundaries.test.tssrc/renderer/src/components/jira-connect-dialog.test.tsxsrc/renderer/src/components/jira-connect-dialog.tsxsrc/renderer/src/components/jira-create-field-payload.test.tssrc/renderer/src/components/jira-create-field-payload.tssrc/renderer/src/components/jira-server-auth-fields.tsxsrc/renderer/src/components/right-sidebar/pr-comment-presentation.test.tssrc/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsxsrc/renderer/src/components/settings/integrations-search.tssrc/renderer/src/components/settings/jira-integration-card.test.tsxsrc/renderer/src/components/settings/jira-integration-card.tsxsrc/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsxsrc/renderer/src/components/sidebar/SidebarToolbar.test.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/renderer/src/runtime/runtime-jira-client.test.tssrc/renderer/src/runtime/runtime-jira-client.tssrc/renderer/src/store/slices/jira.tssrc/renderer/src/test/memory-storage.tssrc/shared/jira-types.tssrc/shared/types.ts
✅ Files skipped from review due to trivial changes (4)
- src/main/jira/auth-headers.ts
- src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.reminder-toast.test.tsx
- src/renderer/src/i18n/locales/en.json
- src/renderer/src/i18n/locales/zh.json
🚧 Files skipped from review as they are similar to previous changes (44)
- src/shared/types.ts
- src/renderer/src/runtime/runtime-jira-client.test.ts
- src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts
- docs/reference/README.md
- src/renderer/src/test/memory-storage.ts
- src/renderer/src/components/feature-interaction-writer-boundaries.test.ts
- src/main/jira/issue-page-fetcher.ts
- src/renderer/src/components/JiraIssueWorkspace.tsx
- src/renderer/src/components/settings/integrations-search.ts
- src/preload/api-types.ts
- src/main/jira/jira-record-primitives.ts
- src/renderer/src/components/right-sidebar/pr-comments-list-selection.test.tsx
- src/renderer/src/runtime/runtime-jira-client.ts
- src/main/jira/issue-rest-routing.ts
- src/main/runtime/rpc/methods/jira.test.ts
- src/renderer/src/components/sidebar/SidebarToolbar.test.tsx
- src/renderer/src/components/settings/jira-integration-card.tsx
- src/renderer/src/components/jira-server-auth-fields.tsx
- src/main/jira/jira-site-url.ts
- src/renderer/src/components/jira-connect-dialog.test.tsx
- src/renderer/src/store/slices/jira.ts
- src/main/ipc/jira.test.ts
- src/main/ipc/jira-connect-args-normalization.ts
- src/renderer/src/components/jira-create-field-payload.test.ts
- src/main/jira/issue-comments.ts
- src/main/ipc/jira.ts
- src/preload/index.ts
- src/main/runtime/rpc/methods/jira.ts
- src/renderer/src/components/settings/jira-integration-card.test.tsx
- src/main/jira/issue-search.ts
- src/main/jira/jira-request.ts
- src/renderer/src/components/jira-create-field-payload.ts
- src/renderer/src/components/jira-connect-dialog.tsx
- src/main/jira/jira-user-identity.ts
- src/main/jira/client.test.ts
- src/shared/jira-types.ts
- src/main/jira/issue-mappers.ts
- src/main/jira/issues.ts
- src/renderer/src/i18n/locales/ja.json
- src/main/jira/issue-metadata.ts
- src/main/jira/issues.test.ts
- src/renderer/src/components/TaskPage.tsx
- src/renderer/src/i18n/locales/ko.json
- src/main/jira/site-storage.ts
Add Server/DC auth, request routing, issue operations, renderer wiring, tests, and contribution documentation for connect/list/search/create/comment/assign/transition.
dcca89f to
25fc610
Compare
Add Server/DC auth, request routing, issue operations, renderer wiring, tests, and contribution documentation for connect/list/search/create/comment/assign/transition.
Summary
Adds Jira Server/Data Center support alongside Jira Cloud in the existing Jira integration.
Users can now connect Jira Cloud or Server/Data Center sites, choose Basic or Bearer auth for Server/DC, and use Jira issue workflows across connect, list, search, create, comment, assign, unassign, and transition. The implementation routes Cloud requests to REST API v3 and Server/DC requests to REST API v2, preserves Cloud behavior, and supports both local IPC and remote runtime RPC paths.
Screenshots
Updated Jira connect dialog with Cloud and Server/Data Center modes.
Testing
pnpm lintpnpm typecheckpnpm testpnpm buildFocused Jira test command run:
pnpm vitest run --config config/vitest.config.ts src/main/jira/client.test.ts src/main/jira/issues.test.ts src/main/ipc/jira.test.ts src/main/runtime/rpc/methods/jira.test.ts src/renderer/src/runtime/runtime-jira-client.test.ts src/renderer/src/store/slices/jira.test.ts src/renderer/src/components/jira-connect-dialog.test.tsx src/renderer/src/components/jira-create-field-payload.test.ts src/renderer/src/components/settings/jira-integration-card.test.tsxResult: 9 test files passed, 81 tests passed.
Full verification run:
pnpm lint: passed, with existing non-fatal warnings.pnpm typecheck: passed.pnpm test: passed, 2297 test files passed, 2 skipped; 23802 tests passed, 29 skipped.pnpm build: passed. The local build emitted existing non-fatal warnings, including the Node engine warning and the optional/usr/local/bin/orca-devsymlink permission warning.AI Review Report
AI code review checked Jira Cloud regression risk, Jira Server/Data Center REST API v2 routing, Basic/Bearer auth handling, connect/list/search/create/comment/assign/transition coverage, IPC/RPC/preload/runtime wiring, renderer state handling, i18n text, pagination behavior, credential cleanup, and contribution-rule compliance.
The review flagged and fixed these issues:
Legacy metadata migration now strips URL credentials/query/hash, and the connect dialog now clears site URL, credentials, auth mode, and error state when closed or after successful connect. Regression tests were added for those behaviors.
The review explicitly checked cross-platform compatibility for macOS, Linux, and Windows, including shortcuts, labels, paths, shell behavior, and Electron-specific platform differences touched by this PR. This PR does not add platform-specific shortcuts, shell commands, or path separators. File path handling remains in Node/Electron path utilities, and remote runtime behavior was reviewed through the Jira RPC wiring.
Security Audit
AI security review covered input handling, auth, secrets, IPC/RPC validation, path handling, logging, dependencies, and Electron runtime boundaries.
Reviewed items:
Follow-up: none required from this review.
Notes
Server/Data Center support uses Jira REST API v2. Jira Cloud continues to use REST API v3.
Remote runtime behavior is supported through the existing Jira runtime RPC bridge.
Local verification was run on a machine using Node v25.2.1, while the repository declares Node 24. The commands completed successfully despite the engine warning.