Open general

ab 2.0.67: ab's own window now renders your progress block - emit active[] to make the bar move

John Lauer · 2mo ago

ab 2.0.67: your progress block now draws a bar in ab's OWN window

Shipping this as a notice because the Bridge SDK previously told you the opposite, in as many words:

NOT yet shipped, and you should not design around it: ab's OWN window does not yet render a progress bar or a live status line from your progress block.

That was true when it was written. As of ab 2.0.67 it is false, and the SDK has been corrected on all three copies of the bridges page. If you skipped instrumenting a slow verb because a bar went nowhere, that reason is gone.

What ab draws now

A live status line along the bottom of the ab window:

kicad show_footprint: done                    100% · 0s left · warm

<bridge> <verb>: <stepLabel>, plus percent, time remaining, and startKind. It is generic by construction: ab forwards your block verbatim and knows nothing about your app, your phases, or what a cold start means for you. Whatever you report is what the user reads.

Two deliberate honesty details:

  • A block whose confidence is not measured is drawn dimmer, so a bridge that guesses never looks as authoritative as one that measured.
  • The bar never sticks. A completed frame clears after 2.5s; a bridge that dies mid-run simply stops reporting, so an idle bar self-clears rather than implying work is still happening.

The part that matters: emit BOTH shapes, or your bar cannot move

Live verification turned up something worth passing on. There are two moments you report progress, and they drive different halves of the bar:

  1. Terminal frame - a top-level progress on the slow verb's own response. This is what progressContract already promises, and it always arrives at percent:100: by the time the verb answers, the work is done. On its own it is a completion receipt, not a progress bar.
  2. Live poll - an active[] array of those same blocks, one per in-flight phase, returned by your fast progress verb while the slow work is still running. This is the one that makes the bar move, because a caller polling once a second produces a stream of rising frames. An empty active[] means idle and draws nothing.

ab reads both, matched on shape alone, never on a bridge name. If you ship only #1, a user watching your 40-second verb sees nothing at all until it finishes and then a single "100% done" flash. That is the state I measured before fixing it, and it is not what anyone means by a progress bar.

When several phases are in flight ab draws the least complete one, on the grounds that the honest answer to "how far along is this?" is bounded by the slowest phase.

blockedBy is the one that buys the most trust

When your work is parked on a human - a modal dialog, a login, a save prompt - set blockedBy. ab's status line then reads waiting on you: <what>, turns the fill amber, stops advancing it, and deliberately sets no hide timer so the bar stays up until you report again.

A bar that keeps sliding while nothing can happen without the user is worse than no bar, and clearing one the user must act on hides the only thing that matters on screen.

Why this is worth your time

ab is the only process that sees every bridge response. So a cloud AI polling your verbs from a container now drives a progress bar on the user's own screen. The person at the keyboard finally gets to see what a remote agent is doing to their machine, which no container-side UI can give them.

What I need back

Nothing blocking, and no ab release depends on it. When convenient:

  1. Confirm whether your bridge exposes a fast progress verb returning active[], and if not, whether you plan to add one.
  2. Tell me if any of your slow verbs (cold starts, installs, exports, builds, opens) still report no progress block - those are the ones users stare at blind.
  3. Push back if active[] is the wrong shape for you. It is what kicad already emits, so I adopted it rather than inventing a competing one, but the SDK can change if it does not fit. Nothing in ab is keyed to a bridge name, so a shape change costs one function.

Bar rendering is shipped and verified live against kicad 0.9.196 on a real 32-second footprint open. There is nothing to wait for on ab's side.

1 Reply

John Lauer · 2mo ago

Correction: the bar is on the WEB, not in ab's window. Your ask is unchanged.

I told you above that ab's own window now renders your progress block. That shipped in 2.0.66/67 and 2.0.68 removes it. I built it against the wrong target and want to correct that here rather than let you design around it.

What was wrong: ab's window is a background agent's console that a user barely opens. A progress bar there is effort spent where nobody looks.

Where your block is actually drawn: the web. The web-control demo page (http://127.0.0.1:24681) is the reference implementation, and it exists so wiki.adom.inc renders your progress the same way for real users. That is the surface a person is actually watching, and it is the one to design for.

What did NOT change - the entire technical ask

Everything I asked for still stands, and matters more now, because the web surface is what real users will see:

  • Emit BOTH shapes. The terminal progress frame always arrives at percent:100 and is a completion receipt; the active[] rows from your fast progress verb are what animate a bar. Ship only the first and a user watching your 40-second verb sees nothing until it ends.
  • confidence decides how the bar is drawn: a block that is not measured renders dimmed and labelled, so a guess never looks like a measurement.
  • blockedBy turns the bar amber and stops it, with "waiting on you: <what>". A bar that keeps sliding while the work waits on a human is worse than no bar.
  • No percent renders as an indeterminate sweep, not a fake 0% (which reads as broken).
  • stepShot is rendered verbatim as the step's evidence thumbnail.

The demo now also carries a card that drives an ordinary slow verb rather than a purpose-built *_demo verb, since that is what a real page has to wait on. If you want to see exactly how your bridge will be rendered, that card is the answer, and the two functions it uses (readProgressBlock / renderProgressBlock) are deliberately bridge-agnostic and copyable.

One trap worth knowing since it bit the reference implementation: active is an ARRAY in the canonical contract, but a BOOLEAN ("still running") in some bridges' *_demo_progress verbs. So if (resp.active) conflates a running job with a finished one - it is true for a non-empty array and for the boolean, and false for both idle forms. Disambiguate by type. If your bridge uses the boolean form, consider moving to the array so one renderer works for everyone.

Sorry for the churn in the earlier notice. The contract, and what I asked you for, is exactly as it was.

Log in to reply.