Skip to content

shaft-intellij: unwrap capture_status/capture_api_status union before reading fields#3954

Merged
MohabMohie merged 1 commit into
mainfrom
ChaosEngine/3949-status-poll-union-unwrap
Jul 21, 2026
Merged

shaft-intellij: unwrap capture_status/capture_api_status union before reading fields#3954
MohabMohie merged 1 commit into
mainfrom
ChaosEngine/3949-status-poll-union-unwrap

Conversation

@MohabMohie

Copy link
Copy Markdown
Contributor

Summary

  • GuidedWorkflowPanel's background status poller (applyStatusPoll, isRecorderActive, activeStatusText, countText, renderStepsFromStatus/parseSteps) read state/active/eventCount/steps off the top level of the polled capture_status/capture_api_status JSON.
  • Since Tool architecture sweep: trim shaft-mcp to 89 tools, canonical tool-index, shaft-cli one-shots, skills router, GitHub-tracking process #3881, CaptureService#status()/apiStatus() (shaft-mcp/src/main/java/com/shaft/mcp/CaptureService.java:319-326, :553-558) return a union (McpCaptureUnionStatus/McpCaptureApiUnionStatus) with the real status nested under webStatus/playwrightStatus/mobileStatusGuidedWorkflowLiveE2ETest's webStatus()/mobileStatus() helpers (GuidedWorkflowLiveE2ETest.java:369-382) already prove this wire shape against a live server.
  • The Guided workflow panel's poller never unwrapped it, so an active recording never rendered as active in the status strip for any backend (WebDriver/Playwright/mobile/API) — confirmed by writing a regression test that fed applyStatusPoll a real union-shaped fixture and watching it fail (status stayed "Recorder idle." instead of rendering "Recording · 2 steps...").
  • Fix: added GuidedWorkflowPanel#unwrapCaptureStatus, which resolves the union down to whichever of webStatus/playwrightStatus/mobileStatus is populated (the union guarantees exactly one is), applied once in applyStatusPoll right after parsing the poll response so every downstream reader sees the correct nested object.

Adjacent finding (not fixed here, per issue #3949's scope boundary)

ShaftAssistantPanel#showCaptureStartDiagnostic (ShaftAssistantPanel.java:3934-3955) has the identical bug: it reads string(statusJson, "state", "") and string(statusJson, "outputPath", expectedOutputPath) directly off the raw capture_status union without unwrapping webStatus. Confirmed by reading the code — not fixed here because ShaftAssistantPanel.java is being actively modified by a concurrent sequential PR chain (#3918-#3922) in the same session; touching it would cause merge conflicts. This should become its own follow-up issue.

Test plan

  • New regression test GuidedWorkflowPanelTest#applyStatusPollUnwrapsTheActiveEngineSectionFromTheUnionResponse — watched RED (status stuck at "Recorder idle." against a union fixture), then GREEN after the fix.
  • ./gradlew test --tests "com.shaft.intellij.ui.GuidedWorkflowPanelTest" — 22/22 tests pass.
  • Full shaft-intellij module ./gradlew test — BUILD SUCCESSFUL, no regressions from widening pollingActive/applyStatusPoll visibility to package-private test seams.

Closes #3949

https://claude.ai/code/session_01NDQpYzvnTbDPYwqDwHQoRz

… reading fields

GuidedWorkflowPanel's background status poller (applyStatusPoll and its
helpers) read state/active/eventCount/steps directly off the top-level
capture_status/capture_api_status JSON. Since #3881, CaptureService#status()/
apiStatus() return a union (McpCaptureUnionStatus/McpCaptureApiUnionStatus)
with the real status nested under webStatus/playwrightStatus/mobileStatus --
GuidedWorkflowLiveE2ETest's webStatus()/mobileStatus() helpers already proved
this wire shape against a live server. The poller never unwrapped it, so an
active recording never rendered as active in the Guided workflow status strip
for any backend.

Fix: unwrap the union to its populated engine section once, right after
parsing the poll response, before any field is read (mirrors the E2E test's
unwrap helpers). Added a regression test that feeds applyStatusPoll a real
union-shaped fixture and asserts on the rendered status text.

Closes #3949

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NDQpYzvnTbDPYwqDwHQoRz
@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 medium

Alerts:
⚠ 1 issue (≤ 0 issues of at least medium severity)

Results:
1 new issue

Category Results
Complexity 1 medium

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@MohabMohie
MohabMohie merged commit f330c5d into main Jul 21, 2026
18 of 19 checks passed
@MohabMohie
MohabMohie deleted the ChaosEngine/3949-status-poll-union-unwrap branch July 21, 2026 14:18
MohabMohie added a commit that referenced this pull request Jul 21, 2026
…agnostic (#3955) (#3975)

shaft-intellij: unwrap capture_status union before reading state/outputPath (#3955)

ShaftAssistantPanel#showCaptureStartDiagnostic read state/outputPath
directly off the raw capture_status/capture_api_status union response
(McpCaptureUnionStatus/McpCaptureApiUnionStatus, design doc amendment
A3, #3881) instead of the populated webStatus/playwrightStatus/
mobileStatus section, so the diagnostic always saw them as absent or
default -- the same bug GuidedWorkflowPanel had before PR #3954.

Extract unwrapCaptureStatus into the AssistantMarkdown shared utility
(already used by both panels for JSON/markdown helpers) and apply it
in showCaptureStartDiagnostic before reading state/outputPath.


Claude-Session: https://claude.ai/code/session_01NDQpYzvnTbDPYwqDwHQoRz

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

GuidedWorkflowPanel status polling may not unwrap capture_status/capture_api_status's union response shape

1 participant