feat(widget): campaign-digest built-in — the home-dashboard digest over the campaign routes (#678) - #690
Merged
Merged
Conversation
…on, routes, escaping (#678) RED state for issue #678: the pins fail against a registry without the campaign-digest built-in (collection failure — the module does not exist yet). String-level assertions per the issue's testing decision: the widget's JS is a source string, so behavior is pinned on the registry entry + the route bodies, not by executing the iframe.
… over the campaign routes (#678) The first consumer of the campaign routes (#658/#662): a tile that fetches /amicode/campaigns, picks the newest ACTIVE campaign (falling back to the newest overall — a finished campaign still deserves a tile until the next one starts), fetches its /amicode/campaign detail, and renders the one-line objective, up to 3 verdict chips (slice/unit + the status cell's leading token — display compression, not parsing), and the §4 blocked section as the needs-you line. Click composes 'Open the campaign <slug>' into chat via amico.prompt. Registered in BUILTIN_SOURCES after jump-back-in (default tile order). Empty state on no campaigns and on any fetch failure (the jump-back-in discipline); esc() throughout; theme via --amc-* custom properties only; re-renders on onConfig/onTheme pushes with an epoch guard against stale fetch writes.
… golden entries (#678) The fork pin (v1.18.10-amicode.18) records /amicode/widgets and the dashboard GET/POST with jump-back-in as the only built-in; the port now ships campaign-digest, so the three registry-projecting entries drift. Same treatment as normalizePortExtensions (#447): strip the port's deliberate extension from BOTH sides so parity stays comparable across the next pin bump; the widget's registration is unit-tested in widgets_registry.test.ts.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 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 |
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.
Closes #678
What
The first consumer of the campaign routes (#662): a built-in home-dashboard widget — the Campaign Inspector's digest surface, shipping before the Work Column tab per the approved Armonia design ("home digest widget ships FIRST — zero navigation").
The tile: eyebrow (campaign name) · one-line objective (ellipsized) · up to 3 verdict chips from the newest ledger (unit + leading status token, keyword-toned: DONE/MERGED → success, BLOCK/FAIL → danger) · the needs-you line (§4 blocked's first line — "⚠ needs you — …" or muted "nothing blocked") · click composes
Open the campaign <slug>into the chat viaamico.prompt.Discipline:
esc()on every interpolation;--amc-*tokens only (no hex, no rgb, no localStorage — the sandboxed frame forbids it); empty state on no campaigns / fetch failure /ok:false;onConfig/onThemere-renders behind an epoch guard; ACTIVE pick is case-insensitive with newest-overall fallback (documented). Unread-state persistence is explicitly v2 (needs a durable last-seen signal the opaque-origin frame can't own).Beyond the repo's string-level test decision, behavioral evidence: the emitted module was executed against a fake bridge across 7 scenarios — active pick, fallback, empty states, fetch rejection, click composition, and a hostile
<script>objective rendering fully escaped.Acceptance criteria — evidence (all six pass; director-verified)
BUILTIN_SOURCESafterjump-back-in, valid tile manifest — registry tests 12/12 + HTTP smoke (/amicode/widgetslists both ids)ok:falsescenariosamico.prompt('Open the campaign <slug>')— asserted in scratch execution--amc-*only — vitest pin + hostile-input render/amicode/widgets+ widget-code route bodies servedDirector gates (independently run)
normalizeBuiltinWidgetDriftstrips it from both sides until the next pin re-record.Merge
Awaiting human review per campaign discipline. Merge order: #662, then this. CI runs on this PR.