Repository navigation
feat(checks): make the Jenkins build tree readable at scale - #40
Merged
Merged
Conversation
The Jenkins details from #39 read the build's stage list but listed every stage in the Checks pane, buried failures under it, kept an Output box that only repeated the build name, and stopped at a bare error when the account could not read the job. - Pane: list only the stages still running and the ones that failed, running first, capped at eight, with a "+N more stages" line — a pipeline can have hundreds. - Detail page: render the stages as a nested tree (stage -> its wfapi flow nodes) like Blue Ocean, with failed and running stages open by default. - Detail page: a Failures block under the run header names each failed stage and its error text, so "what broke" needs no scrolling. - Detail page: drop the Output box for a stage list; the build metadata is the run summary. - Settings: a Jenkins read failure the user can fix (no server, rejected token, no permission) now shows an "Open Jenkins settings" button that deep-links to the Jenkins card. Main reads each stage's own wfapi/describe (its _links.self.href, bounded to 40 requests at six concurrent, failed/running first under a four-second budget) for the steps and failure text, and carries the flow nodes on an optional PRCheckStep.children. The Jenkins node id is kept so repeated stage names (loops, parallel branches) cannot collide as React keys.
Five files exceed the oxlint max-lines budget on nplez1/main and have no suppression, so the whole-repo `pnpm exec oxlint` in the static-analysis job fails for every PR cut from it. They were pushed over by fork-only commits (`#34`, and three direct commits) that never ran PR CI. The repo's rule is to split rather than suppress, so this extracts cohesive pieces: - filesystem-watcher.test.ts: the local/WSL lifecycle tests move to filesystem-watcher-local-lifecycle.test.ts. - filesystem-watcher-local-subscription.ts: scheduleLocalWatcherTeardown moves to filesystem-watcher-local-teardown.ts. - ssh-target-cleanup.ts: the per-tab session helpers move to ssh-target-tab-sessions.ts. - ai-vault-session-refresh.ts: the session-ids key moves to ai-vault-session-ids.ts. - accounts-search.ts: the Grok and Cursor search entries move to accounts-search-extra-providers.ts and are re-exported. No behavior change; the affected suites pass.
nplez1
added a commit
that referenced
this pull request
Sep 29, 2026
* feat(checks): make the Jenkins build tree readable at scale The Jenkins details from #39 read the build's stage list but listed every stage in the Checks pane, buried failures under it, kept an Output box that only repeated the build name, and stopped at a bare error when the account could not read the job. - Pane: list only the stages still running and the ones that failed, running first, capped at eight, with a "+N more stages" line — a pipeline can have hundreds. - Detail page: render the stages as a nested tree (stage -> its wfapi flow nodes) like Blue Ocean, with failed and running stages open by default. - Detail page: a Failures block under the run header names each failed stage and its error text, so "what broke" needs no scrolling. - Detail page: drop the Output box for a stage list; the build metadata is the run summary. - Settings: a Jenkins read failure the user can fix (no server, rejected token, no permission) now shows an "Open Jenkins settings" button that deep-links to the Jenkins card. Main reads each stage's own wfapi/describe (its _links.self.href, bounded to 40 requests at six concurrent, failed/running first under a four-second budget) for the steps and failure text, and carries the flow nodes on an optional PRCheckStep.children. The Jenkins node id is kept so repeated stage names (loops, parallel branches) cannot collide as React keys. * fix(lint): split files over the max-lines budget Five files exceed the oxlint max-lines budget on nplez1/main and have no suppression, so the whole-repo `pnpm exec oxlint` in the static-analysis job fails for every PR cut from it. They were pushed over by fork-only commits (`#34`, and three direct commits) that never ran PR CI. The repo's rule is to split rather than suppress, so this extracts cohesive pieces: - filesystem-watcher.test.ts: the local/WSL lifecycle tests move to filesystem-watcher-local-lifecycle.test.ts. - filesystem-watcher-local-subscription.ts: scheduleLocalWatcherTeardown moves to filesystem-watcher-local-teardown.ts. - ssh-target-cleanup.ts: the per-tab session helpers move to ssh-target-tab-sessions.ts. - ai-vault-session-refresh.ts: the session-ids key moves to ai-vault-session-ids.ts. - accounts-search.ts: the Grok and Cursor search entries move to accounts-search-extra-providers.ts and are re-exported. No behavior change; the affected suites pass.
nplez1
added a commit
that referenced
this pull request
Oct 1, 2026
* feat(checks): make the Jenkins build tree readable at scale The Jenkins details from #39 read the build's stage list but listed every stage in the Checks pane, buried failures under it, kept an Output box that only repeated the build name, and stopped at a bare error when the account could not read the job. - Pane: list only the stages still running and the ones that failed, running first, capped at eight, with a "+N more stages" line — a pipeline can have hundreds. - Detail page: render the stages as a nested tree (stage -> its wfapi flow nodes) like Blue Ocean, with failed and running stages open by default. - Detail page: a Failures block under the run header names each failed stage and its error text, so "what broke" needs no scrolling. - Detail page: drop the Output box for a stage list; the build metadata is the run summary. - Settings: a Jenkins read failure the user can fix (no server, rejected token, no permission) now shows an "Open Jenkins settings" button that deep-links to the Jenkins card. Main reads each stage's own wfapi/describe (its _links.self.href, bounded to 40 requests at six concurrent, failed/running first under a four-second budget) for the steps and failure text, and carries the flow nodes on an optional PRCheckStep.children. The Jenkins node id is kept so repeated stage names (loops, parallel branches) cannot collide as React keys. * fix(lint): split files over the max-lines budget Five files exceed the oxlint max-lines budget on nplez1/main and have no suppression, so the whole-repo `pnpm exec oxlint` in the static-analysis job fails for every PR cut from it. They were pushed over by fork-only commits (`#34`, and three direct commits) that never ran PR CI. The repo's rule is to split rather than suppress, so this extracts cohesive pieces: - filesystem-watcher.test.ts: the local/WSL lifecycle tests move to filesystem-watcher-local-lifecycle.test.ts. - filesystem-watcher-local-subscription.ts: scheduleLocalWatcherTeardown moves to filesystem-watcher-local-teardown.ts. - ssh-target-cleanup.ts: the per-tab session helpers move to ssh-target-tab-sessions.ts. - ai-vault-session-refresh.ts: the session-ids key moves to ai-vault-session-ids.ts. - accounts-search.ts: the Grok and Cursor search entries move to accounts-search-extra-providers.ts and are re-exported. No behavior change; the affected suites pass.
nplez1
added a commit
that referenced
this pull request
Oct 6, 2026
* feat(checks): make the Jenkins build tree readable at scale The Jenkins details from #39 read the build's stage list but listed every stage in the Checks pane, buried failures under it, kept an Output box that only repeated the build name, and stopped at a bare error when the account could not read the job. - Pane: list only the stages still running and the ones that failed, running first, capped at eight, with a "+N more stages" line — a pipeline can have hundreds. - Detail page: render the stages as a nested tree (stage -> its wfapi flow nodes) like Blue Ocean, with failed and running stages open by default. - Detail page: a Failures block under the run header names each failed stage and its error text, so "what broke" needs no scrolling. - Detail page: drop the Output box for a stage list; the build metadata is the run summary. - Settings: a Jenkins read failure the user can fix (no server, rejected token, no permission) now shows an "Open Jenkins settings" button that deep-links to the Jenkins card. Main reads each stage's own wfapi/describe (its _links.self.href, bounded to 40 requests at six concurrent, failed/running first under a four-second budget) for the steps and failure text, and carries the flow nodes on an optional PRCheckStep.children. The Jenkins node id is kept so repeated stage names (loops, parallel branches) cannot collide as React keys. * fix(lint): split files over the max-lines budget Five files exceed the oxlint max-lines budget on nplez1/main and have no suppression, so the whole-repo `pnpm exec oxlint` in the static-analysis job fails for every PR cut from it. They were pushed over by fork-only commits (`#34`, and three direct commits) that never ran PR CI. The repo's rule is to split rather than suppress, so this extracts cohesive pieces: - filesystem-watcher.test.ts: the local/WSL lifecycle tests move to filesystem-watcher-local-lifecycle.test.ts. - filesystem-watcher-local-subscription.ts: scheduleLocalWatcherTeardown moves to filesystem-watcher-local-teardown.ts. - ssh-target-cleanup.ts: the per-tab session helpers move to ssh-target-tab-sessions.ts. - ai-vault-session-refresh.ts: the session-ids key moves to ai-vault-session-ids.ts. - accounts-search.ts: the Grok and Cursor search entries move to accounts-search-extra-providers.ts and are re-exported. No behavior change; the affected suites pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
Orca can now read a Jenkins build and paint its pipeline. But the first pass was too much: the
Checks pane listed every stage of a pipeline that can have hundreds, the failing stage was buried
underneath, an "Output" box only repeated the build's name, and a Jenkins permissions problem was a
dead-end sentence. This makes the pane short, draws the pipeline as a tree like Blue Ocean's, puts
the failures on top, and turns a fixable Jenkins error into a button that opens Settings.
What Changed
Before: expanding a Jenkins check listed every stage of the build — hundreds of rows for a
large pipeline — with the failed and still-running stages mixed in. The check-details tab repeated
the full stage list with no nesting, opened onto an Output box whose only content was the build's
display name, and reported a permissions problem with a sentence you could not act on. A build's
failure text was not read at all.
After:
with a
+N more stagesline. A passing stage is no longer noise.duration per node; the failed and running stages are open by default.
text, so "what broke" needs no scrolling.
now shows an Open Jenkins settings button that deep-links to the Jenkins card in
Settings → Integrations.
The mechanism. The pane reduction is
paneCheckStepsinsrc/shared/check-step-visibility.ts.The tree and failure text come from one more bounded round of reads: main follows each stage's own
wfapi/describe(_links.self.href, resolved against the build and refused unless it stays underthe configured server), bounded to 40 requests at six concurrent, failed/running first, under a
four-second budget. The mapper nests the
stageFlowNodeson an optionalPRCheckStep.childrenand lifts the failing node's
error.messageonto the stage, so the flat pane list and the nestedtree read the same data. The Jenkins node
idis carried so repeated stage names cannot collide asReact keys. The settings affordance is a typed
JenkinsCheckDetailsErrorwhose reason becomes aserializable
errorActionon the pane and tab state — not a callback, because that state ispersisted — cleared on every success and retry.
Why
A cap with priority, not an unbounded fan-out. A pipeline can have hundreds of stages, and the
Blue Ocean tree needs each stage's own data.
wfapiexposes that one stage at a time, so a fan-outis unavoidable; fetching failed and running stages first means the cap can only ever hide the steps
of later passing stages, never the failure that brought the user here. The four-second budget is the
real latency guard, so the request cap is only a server-load ceiling.
One nested, provider-neutral field rather than a Jenkins-only tree type.
childrenanderrorMessageare generic enough to cross IPC, and threading a second tree throughPRCheckRunDetailsand every surface would be more churn. The flat consumers explicitly do notrecurse — that is documented on the type and covered by a test — so outcomes are never double-counted.
The node id as the key. Loops and parallel branches repeat stage names, and parallel branches can
share a start time or have none; a
name + startedAtkey drops or duplicates rows. The id isJenkins' own and unique per run.
A structured error action, not message matching.
failureMessagelocalizes at throw time, sothe reason is gone by the time a surface decides whether to offer a link. The typed error carries it
forward, and only the fixable reasons (not-configured, unauthorized, forbidden) offer the button.
Alternatives considered: depending on the Blue Ocean REST
/nodesendpoint for a one-shot tree(rejected — it needs the Blue Ocean plugin, which we cannot assume on
psci-jenkins.adobe.io, and amissing plugin would silently empty the pane); removing the Output box for every provider (rejected —
it is real check output for GitHub and GitLab, so it is dropped only for a stage list).
Linked Issue
None filed — nothing to link (same as #39). Say the word if you want one opened and referenced here.
Visual Proof
No screenshots: this needs a live Jenkins plus a running app, and capturing one here would be
dishonest. What follows is the rendered text of the components, whitespace-normalized, taken
from the component tests (
jenkins-check-row-details.test.tsx,CheckRunDetailsPanel.jenkins.test.tsx) — real renders, not hand-written.Before — the pane's stage list was every stage, including the passing ones:
After — only what is running and what failed, running first:
After — the check-details tab, top down:
Testing
pnpm tc(all projects) clean.pnpm run check:code-quality:changedclean (all seven scans, including design-system and ReactDoctor).
Localization extraction / catalogs / coverage green;
check:max-lines-ratchetgreen.Affected suites: full
src/shared,src/main/jenkins, and the wholeeditor,right-sidebarand
storedirectories — green (≈17,000 tests across those runs).New coverage worth naming: pane filtering/cap/order (6), rendered settings button and its clearing
after a retry (2), the stage tree including a 250-stage list with 50 repeated names and no key
collision (2), the failure summary (2), Output-box removal for a stage list (1), settings-error
typing (2), reducer identity for a repeated patch (1), a stage detail that never answers ends at
the budget (1), and the 40-request cap (1).
Platforms: macOS only. No live Jenkins was exercised; every endpoint interaction is mocked.
I manually tested these changes locally
Automated tests added/updated, or explained why not below
AI Disclosure
Implemented by Pi (coding agent), with an independent review pass from the advisor escalation
before finalizing. That review found three real issues, all fixed: React key collisions for repeated
stage names (now keyed on the Jenkins node id), a regression where a check whose only output was a
title lost its Output box (restored for non-stage providers), and an inaccurate comment claiming the
request cap could never hide failure text.
Review
Worth a reviewer's eye:
fetched first, so the failure path is unaffected; a very large pipeline will show every stage name
but only expand the failed/running ones plus the earliest passing ones. Raising the cap is a
one-constant change if we want fuller coverage (
MAX_STAGE_DETAIL_REQUESTS).visibleCheckSteps,paneCheckStepsandsummarizeJobStepsread top-level steps only; onlyCheckStageTreedescends intochildren.A test pins the pane's non-recursion.
[data-settings-section= "integrations-jenkins"], which the Jenkins card now sets. The id is a lib constant shared by thecard and both surfaces.
hasOutput = (title || summary || text) && !showsStageList— the drop isscoped to a stage list, not to a provider name.
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
max-linesbudgeton
nplez1/main(pre-existing — pushed over by fork-only commits that never ran PR CI), which wasfailing the whole-repo lint gate for every PR cut from it. No behavior change; the repo's rule is
to split, not suppress.
prefix (or the build origin when unconfigured), so the
Authorizationheader never travels to ahost we did not configure.
macOS was run.
PRCheckStep.id/children/errorMessageand the newerrorActionare optional, so an older client ignores them.
budget; the pane is capped at eight rows regardless of pipeline size.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)— locally:
pnpm tc, the affected suites and every affectedpnpm lintgate are green; thefull
pnpm testandpnpm buildwere left to CI.