Skip to content

feat(jira): load attachment images outside issue Markdown - #28631

Merged
nwparker merged 12 commits into
mainfrom
nwparker/jira-attachment-protocol
Oct 14, 2026
Merged

nwparker merged 12 commits into
mainfrom
nwparker/jira-attachment-protocol

Conversation

@nwparker

@nwparker nwparker commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 18 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1735 $\color{#cf222e}{\Huge{\mathbf{−}}}$​19 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1716
Prod 45 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1382 $\color{#cf222e}{\Huge{\mathbf{−}}}$​156 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1226

ELI5

Jira screenshots load separately from issue text, so descriptions and comments stay small. Images that exceeded the previous inline limit can appear in the issue and open in the existing lightbox. Reconnecting the issue's host retries an image already on screen.

What Changed

  • Issue and comment reads return short image references. The desktop retrieves authenticated bytes through its image protocol; remote hosts send each image through an authenticated binary subscription. Jira credentials remain in the execution host.
  • Peers negotiate image support and preserve existing issue/comment handlers for older installations. Transfers carry separate identities and sequence numbers.
  • Main and renderer image caches each account for up to 24 MiB of encoded image payloads / 96 entries; decoded pixels and in-flight copies use additional memory. New downloads allow three active requests, 96 pending distinct images and 8 MiB per image. Each description/comment read admits 24 references; combined 48-reference reads are covered.
  • Renderer host invalidation cancels pending image reads, verified recovery retries mounted images, and stale pairing callbacks cannot replace current results. Scoped gateway URLs and server installation paths remain supported.
  • Desktop allows the attachment protocol; native mobile shells allow Blob image URLs. Current issue editing, hydration, required transition comments, timeline refresh and captured-host routing are preserved. Four unchanged project-metadata IPC handlers move into a dedicated module to keep the registration file within its existing limit.

Why

Embedding base64 images retained megabytes in issue caches and enlarged text transfers. Separate downloads begin when an image mounts and provide cancellation and byte limits. Plain attachment URLs would put authentication handling in the renderer and would not support remote execution hosts.

This extends Frank (@lifefloating)'s merged #8938, including its fixes with Brennan Benson, using the existing attachment discovery.

Linked Issue

Fixes #10724

Visual Proof

Final hidden macOS Electron/CDP proof at 91b449eec95, composed onto landed main 624c4148cc88, passes 48 checks with nine screenshots. It runs production components, detail/image clients, cache, mutation queue and binary decoder with a synthetic store, RPC endpoint and subscriptions. Checks cover recovery, cancellation, stale pairing callbacks, lightbox, 48 description/comment images, byte bounds, title/hydration preservation, required transition comments and obsolete timeline reads.

Recovered image after reconnect, retaining the saved title and hydrated fields:

Final recovered image and saved title

Required transition comment immediately appears in the refreshed timeline:

Final required transition comment timeline

The six existing images below retain the earlier fixture evidence. They are historical; the final branch is verified by the checks above. The first fixture exercised the authenticated local protocol and remote handler with a fixture token held in the main process. The later recovery fixture ran production renderer clients with synthetic transports.

Before: the 3,240,054-byte image exceeds the previous 2 MiB inline limit.

Before

Local authenticated image:

Local after

Remote binary image:

Remote after

Existing lightbox:

Lightbox

Mounted image before recovery:

Disconnected image fallback

After recovery, with saved title, hydrated fields and comment preserved:

Recovered image and saved title

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • Final 91b449eec95: 410 focused tests across 54 files pass, covering authentication, bounded transfer/cache behavior, legacy compatibility, cancellation, reconnect, captured owners, editing and timeline lifetimes.

  • Exact branch node and renderer typechecks pass with unchanged source hashes.

  • All seven changed-code quality stages pass across 58 files; full-file lint passes for 98 files and formatting for 100. Anti-slop, the 1,106-read routing ratchet, regenerated RPC catalog and diff checks pass. Two inherited routing ceilings were lowered to match current main.

  • Fresh hidden Electron/CDP proof passes 48/48 checks. All 226 prepared/source hashes stayed unchanged, the renderer reported no page errors, and the owned background app processes were stopped with both ports clear.

  • Latest CI snapshot: static/typechecks, mobile verify and bundle, relay, wire compatibility, Linux/Windows packaging and Windows serve checks pass; five test shards remain pending.

  • Earlier headless mobile-web/CSP checks passed 32 tests on 354020e7d04; those are historical. Local checks do not claim live Jira/auth/socket/SSH, physical mobile, a full build or Linux/Windows execution. Image mounts trigger fetching; viewport laziness is not implemented. Padded PNGs verify encoded byte bounds, not decoded pixel memory.

Review

Independent final source review finds no concrete defect and rates the scoped change Low risk. It covers authentication, transfer isolation, cancellation, bounded caches, capability exports/order, older-peer behavior and preservation of landed issue actions, transition comments, board filters and timeline lifetimes. All four addressed review threads remain resolved. Independent artifact review also verifies all 48 assertions, 226 source hashes, fixture/driver checksums, nine screenshots and cleanup; no blocking defect found.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

CLI/scoped-auth prerequisites and the assignee/board changes have landed; this branch composes actual main 624c4148cc88 and contains no separate CLI/auth feature changes. The workspace differs from that main only by its captured image-owner prop.

Pending legacy inline reads and cancellable byte reads use separate request domains; completed image bytes share the bounded cache. Both request orders and completed-cache reuse are tested. Simultaneous cold legacy/new reads may download the same attachment twice. New binary frames require negotiated support, and the existing five mobile Jira read methods remain alongside attachment-image reads.

External token-file reload (#28594) does not immediately revoke cached host attachment bytes or rendered Blob URLs. Same-process disconnect/reconnect clears the host attachment cache.

Checklist

  • This PR is small and focused — attachment loading is the sole feature, spanning 64 files against the composed base
  • I explained what changed and why (the user-facing before/after, mechanism, and approach)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (focused checks and exact node/web compilers pass; a full local suite/build was not run and CI test shards remain pending)

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f67b5c8f-f8a3-4501-8b1d-74e1b4bda06a
📥 Commits

Reviewing files that changed from the base of the PR and between 570a949 and 91b449e.

⛔ Files ignored due to path filters: 1
  • src/shared/rpc-contract/rpc-params-catalog.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing: 23
  • config/focus-setting-read-baseline.txt
  • src/main/ipc/jira-project-metadata-registration.test.ts
  • src/main/ipc/jira-project-metadata.ts
  • src/main/ipc/jira.ts
  • src/main/jira/attachment-image-cache.ts
  • src/main/jira/attachment-legacy-cancellation.test.ts
  • src/main/jira/jira-issue-read.ts
  • src/main/runtime/rpc/methods/jira.test.ts
  • src/main/runtime/rpc/methods/jira.ts
  • src/main/runtime/runtime-jira-commands.ts
  • src/main/runtime/runtime-rpc/runtime-rpc-mobile-paired-desktop-methods.ts
  • src/preload/api/jira-api.ts
  • src/preload/api/jira-bridge.ts
  • src/renderer/src/components/JiraIssueWorkspace.tsx
  • src/renderer/src/components/jira-issue-workspace-image-owner.test.tsx
  • src/renderer/src/runtime/runtime-jira-client.test.ts
  • src/renderer/src/runtime/runtime-jira-client.ts
  • src/renderer/src/runtime/runtime-jira-detail-client.test.ts
  • src/renderer/src/runtime/runtime-jira-detail-client.ts
  • src/renderer/src/runtime/runtime-jira-detail-images.test.ts
  • src/shared/jira-detail-capabilities.ts
  • src/shared/protocol-version.ts
  • src/shared/rpc-contract/jira-params.ts
🚧 Files skipped from review as they are similar to previous changes: 1
  • config/focus-setting-read-baseline.txt

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

📝 Walkthrough

Jira issue and comment reads can request attachment references instead of embedding image data. Local reads use bounded, authenticated downloads and a custom image protocol. Remote runtimes transfer image data in binary frames. The renderer caches and displays images by runtime target, migrates supported legacy inline images, and invalidates cache entries when host status changes. CSP declarations allow the image sources used by the new paths. Project metadata IPC registration also moves to a dedicated module.

Priority: ➖ Normal

Merge Risk: 🟡 Moderate · up to 91b44

Some Jira attachment images can still fail to load, particularly with non-REST attachment paths, crowded download queues, or a transient host disconnect. Resolve or explicitly accept those limitations before merging.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Out of Scope Changes check Warning The PR includes unrelated Jira project-metadata IPC changes. src/main/ipc/jira.ts removes four project-metadata handlers, while src/main/ipc/jira-project-metadata.ts and its tests add their regist… Remove the project-metadata IPC extraction and its dedicated tests from this PR, or provide a direct technical dependency that is required for the #10724 image-loading implementation.
Docstring Coverage Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 130 functions across 77 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Linked Issues check Passed The PR meets the coding requirements in #10724. It registers the privileged orca-jira-image scheme and permits the required image sources in desktop and mobile CSP. Grants and main-process reads kee…
Title check Passed The title clearly and concisely describes the main change: loading Jira attachment images outside issue Markdown.
Description check Passed The description is comprehensive and covers the required sections, including user impact, implementation, rationale, linked issue, visual proof, testing, compatibility, security, and known limitations…
Full details: Out of Scope Changes check

Explanation

The PR includes unrelated Jira project-metadata IPC changes. src/main/ipc/jira.ts removes four project-metadata handlers, while src/main/ipc/jira-project-metadata.ts and its tests add their registration in a separate module. These changes do not implement attachment references, authenticated image loading, image transfer, image caching, or image compatibility for #10724.

Full details: Docstring Coverage

Explanation

Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 130 functions across 77 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e69aedc6-a48f-4ae6-9702-0d8a4bd58675
📥 Commits

Reviewing files that changed from the base of the PR and between 1c274cc and cfbc768f9eaf6433051026bbf2716020860b1689.

⛔ Files ignored due to path filters: 1
  • src/shared/rpc-contract/rpc-params-catalog.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing: 106
  • config/scripts/generate-bundled-skill-guides.mjs
  • config/scripts/mobile-web-app-render.test.mjs
  • config/scripts/mobile-web-app-source-control-render.test.mjs
  • docs/site/content/docs/review/jira.mdx
  • mobile/modules/orca-mobile-web-shell/android/src/main/java/expo/modules/orcamobilewebshell/MobileWebShellCsp.kt
  • mobile/modules/orca-mobile-web-shell/android/src/test/java/expo/modules/orcamobilewebshell/MobileWebShellCspTest.kt
  • mobile/modules/orca-mobile-web-shell/ios/MobileWebShellCsp.swift
  • mobile/modules/orca-mobile-web-shell/tests/MobileWebShellChecks.swift
  • resources/skills/current-manifest.json
  • skill-guides/jira-tickets.md
  • skill-guides/orca-jira.md
  • skill-stubs/jira-tickets.md
  • skill-stubs/orca-jira.md
  • skills/jira-tickets/SKILL.md
  • skills/orca-jira/SKILL.md
  • src/cli/args.ts
  • src/cli/bundled-skill-guides.ts
  • src/cli/command-body-input.ts
  • src/cli/handler-group-manifest.ts
  • src/cli/handlers/jira-write.ts
  • src/cli/handlers/jira.ts
  • src/cli/index-jira.test.ts
  • src/cli/jira-command-surface.test.ts
  • src/cli/jira-format.ts
  • src/cli/jira-handler-group.ts
  • src/cli/jira-target.ts
  • src/cli/linear-request-builders.ts
  • src/cli/reference-handler-group.ts
  • src/cli/specs/index.ts
  • src/cli/specs/jira.ts
  • src/main/ipc/jira.ts
  • src/main/jira/__mocks__/jira-client-module.ts
  • src/main/jira/attachment-discovery.ts
  • src/main/jira/attachment-image-bytes.ts
  • src/main/jira/attachment-image-cache.ts
  • src/main/jira/attachment-image-grants.ts
  • src/main/jira/attachment-image-protocol.ts
  • src/main/jira/attachment-image-read.test.ts
  • src/main/jira/attachment-image-read.ts
  • src/main/jira/attachment-image-references.test.ts
  • src/main/jira/attachment-images.ts
  • src/main/jira/attachment-meta.ts
  • src/main/jira/auth-http-fixture.ts
  • src/main/jira/authenticated-request-image-limit.test.ts
  • src/main/jira/authenticated-request.ts
  • src/main/jira/client-scoped-token.test.ts
  • src/main/jira/client.test.ts
  • src/main/jira/client.ts
  • src/main/jira/cloud-gateway.ts
  • src/main/jira/credential-verification.ts
  • src/main/jira/gateway-base-url.ts
  • src/main/jira/jira-agent-read.test.ts
  • src/main/jira/jira-api-error.ts
  • src/main/jira/jira-issue-comments.ts
  • src/main/jira/jira-issue-create-metadata.ts
  • src/main/jira/jira-issue-media.ts
  • src/main/jira/jira-issue-mutations.test.ts
  • src/main/jira/jira-issue-mutations.ts
  • src/main/jira/jira-issue-read.ts
  • src/main/jira/jira-issue-search.ts
  • src/main/jira/jira-project-queries.ts
  • src/main/jira/jira-read-failure.ts
  • src/main/jira/jira-transition-queries.ts
  • src/main/jira/site-credential-store.ts
  • src/main/jira/site-identity.ts
  • src/main/runtime/rpc/methods/jira-attachment-image.test.ts
  • src/main/runtime/rpc/methods/jira-attachment-image.ts
  • src/main/runtime/rpc/methods/jira.test.ts
  • src/main/runtime/rpc/methods/jira.ts
  • src/main/runtime/runtime-jira-commands.ts
  • src/main/runtime/runtime-rpc/runtime-rpc-mobile-paired-desktop-methods.ts
  • src/main/startup/cli-command-names.ts
  • src/main/startup/main-process-preflight.ts
  • src/main/startup/main-process-ready-foundation.ts
  • src/preload/api/jira-api.ts
  • src/preload/api/jira-bridge.ts
  • src/renderer/index.html
  • src/renderer/src/components/JiraIssueWorkspace.tsx
  • src/renderer/src/components/jira-attachment-image.test.tsx
  • src/renderer/src/components/jira-attachment-image.tsx
  • src/renderer/src/components/jira-connect-credential-guide.tsx
  • src/renderer/src/components/jira-connect-dialog.tsx
  • src/renderer/src/components/jira-connect-scoped-token.test.tsx
  • src/renderer/src/components/jira-issue-markdown.tsx
  • src/renderer/src/components/jira-issue-workspace-content.tsx
  • src/renderer/src/components/sidebar/CommentMarkdown.tsx
  • src/renderer/src/components/sidebar/MarkdownImageLightbox.tsx
  • src/renderer/src/components/sidebar/comment-markdown-element-renderers.tsx
  • src/renderer/src/hooks/ipc-events/app-lifetime-ipc-bridge.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/runtime/runtime-jira-client.test.ts
  • src/renderer/src/runtime/runtime-jira-client.ts
  • src/renderer/src/runtime/runtime-jira-connection-status.test.ts
  • src/renderer/src/runtime/runtime-jira-connection-status.ts
  • src/renderer/src/runtime/runtime-jira-detail-client.ts
  • src/renderer/src/runtime/runtime-jira-image-cache.test.ts
  • src/renderer/src/runtime/runtime-jira-image-cache.ts
  • src/renderer/src/runtime/runtime-jira-image-client.test.ts
  • src/renderer/src/runtime/runtime-jira-image-client.ts
  • src/renderer/src/store/slices/jira-connection-actions.ts
  • src/shared/jira-agent-capability.ts
  • src/shared/jira-attachment-image.ts
  • src/shared/jira-image-stream-frame.ts
  • src/shared/jira-types.ts
  • src/shared/protocol-version.ts
  • src/shared/rpc-contract/jira-params.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

Comment thread skill-guides/orca-jira.md Resolved
Comment thread src/main/jira/attachment-image-bytes.ts Resolved
Comment thread src/main/jira/authenticated-request.ts Resolved
@nwparker
nwparker force-pushed the nwparker/jira-attachment-protocol branch from 8804a66 to 570a949 Compare October 14, 2026 10:17
# Conflicts:
#	config/focus-setting-read-baseline.txt
#	src/main/runtime/rpc/methods/jira.ts
#	src/preload/api/jira-bridge.ts
#	src/renderer/src/components/JiraIssueWorkspace.tsx
#	src/renderer/src/components/jira-issue-workspace-request-lifetime.test.tsx
#	src/renderer/src/runtime/runtime-jira-client.ts
#	src/renderer/src/runtime/runtime-jira-detail-client.test.ts
#	src/renderer/src/runtime/runtime-jira-detail-client.ts
#	src/shared/protocol-version.ts
#	src/shared/rpc-contract/rpc-params-catalog.generated.ts
@nwparker
nwparker merged commit a0c46b4 into main Oct 14, 2026
35 of 37 checks passed
nwparker added a commit that referenced this pull request Oct 14, 2026
## ELI5

Keep the test suite working with the Jira features that have just landed. There is no visible app change.

## What Changed

The host-picker test now expects the host-qualified selection the parent already accepts. The startup fixture provides Electron's protocol handler and verifies that ready installs the Jira image scheme. Jira edit tests use exported wrappers with module-local setters that are cleared on unmount, preserving the issue/source switch tests without the banned mutable function export.

The WSL storage inventory classifies Jira list columns, linked-view choice and prompt templates as device preferences, matching their keys and the existing Linear policy. Skill-guide tests check the actual generated discovery projection rather than assuming it is shorter than every full guide or uses one fixed phrase. The cache test follows the headless workflow's deliberate removal of its push trigger; cache-warmer checks remain intact.

## Why

Final CI found six stale integration assumptions after the Jira batch. Updating the fixtures and inventory preserves the landed behavior and the underlying checks. Changing production code, padding the Jira guide, or restoring an intentionally removed workflow trigger would change the product to satisfy incorrect test assumptions.

## Linked Issue

Follow-up to #28622, #28631 and #28592. The existing headless trigger policy was introduced in #28664.

## Visual Proof

N/A — tests, test fixtures and storage inventory declarations only; no visual or interaction change.

## Testing

- [x] Automated tests updated.
- [x] 196 focused tests across nine files pass on macOS, covering every failed shard assertion, fixture consumers and the headless workflow policy.
- [x] Node and web typechecks pass; all seven changed-code quality stages, formatting and diff checks pass.
- Reproduced five failing assertions in startup/export/storage tests and the skill projection failure before the repairs. The host-picker owner also reproduced the stale selection failure before correcting it.
- Final full CI will run on this PR. The prior Ubuntu 22.04 persistence job crashed in the native watcher build before persistence tests ran; this change does not claim a Linux release, live Jira or real SSH pass.

## Review

Independent source review found no issues; all six reviewed file hashes and the complete diff match committed head `aa703eb50147ba95646cb82f10b6d86b4f890fc4`. Risk: low. No authentication, network, protocol implementation, workflow, renderer behavior, remote messages or migration rewrite logic changes.

## Agent skill upstream boundary

- [x] Not applicable; no upstream skill-installer source or artifacts copied.

## Notes

The three storage keys contain device-level preferences, without workspace paths or identifiers. Tests preserve host disambiguation and issue/source switching. Platform, SSH and provider behavior remains in the existing implementations.

## Checklist

- [x] Small and focused.
- [x] Explained the before/after, mechanism and choice of approach.
- [x] Visual proof marked N/A with a reason.
- [x] Self-reviewed for correctness and cleanup.
- [x] Cross-platform and SSH impact considered.
- [x] Focused tests, types, formatting and quality checks pass; full CI covers the broader build.
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.

Replace Jira data-URL inline images with custom protocol handler

1 participant