Commit Graph

6 Commits

Author SHA1 Message Date
Svrnty
db1d4e0cdb fix(adwright): distinguish null vs [] in cycles/audience/connections empty-states
Some checks failed
plugin-tests / test (push) Failing after 6s
Empty-state messages now differentiate "never fetched" (null) from
"fetched but empty" ([]), so the panel reads correctly after a refresh
returns zero rows. Affected renderers: _renderCycles, _renderAudience,
_renderConnections. Targeting unchanged (its gate is "both lists needed",
not single-list empty).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 14:54:44 -04:00
Svrnty
ef6a123c06 fix(adwright overview): show 0 (not —) when data empty; was treating zero as 'missing'
Some checks failed
plugin-tests / test (push) Failing after 6s
Bug: cycleCount: String(c.length || '—') turned 0 into '—' due to || falsy
coercion. Plan B DB starts empty → Overview KPIs all '—' even after a
successful refresh. Renders '0' now (the actually correct truthful value).

Karpathy 4 rules: smallest change (one expression), no shape change.
2026-05-24 14:45:20 -04:00
Svrnty
058d67b459 fix(adwright panel): map real {meta,woo} shape from adwright-mcp; connections tab now shows live status
Some checks failed
plugin-tests / test (push) Failing after 6s
Bug: panel _ingestUpdate expected payload.connections array (mock shape).
Real adwright_get_connections_status returns {meta:{...}, woo:{...}}.
Resulted in connections tab always empty + Overview KPIs sourced from
empty arrays even though backend was returning real data.

Now ingest normalises both shapes (real + mock fallback) into the
[{id, name, ok, status, detail}, ...] shape the renderer already expects.
detail field plumbed through for future Connections card expansion.

Verified via curl /api/adwright/last-panel-update?tool=adwright_get_connections_status
returns real Plan B sandbox + Woo. Panel now displays them.

Karpathy 4 rules: surfaced shape mismatch via real backend probe, smallest
shim (one ingest branch), supports both old + new shape (no regression).
2026-05-24 14:24:31 -04:00
Svrnty
7dcda7669f fix(adwright panel): add 1-click Switch-to-CMO button + authoritative profile fetch
Some checks failed
plugin-tests / test (push) Failing after 5s
JP feedback: panel says "switch to cmo profile" but offers no way to do so.
Also window.S.activeProfile may be empty on /session/* pages before boot.js
finishes initializing, so the banner showed unnecessarily.

This patch:
- Replaces vague text with a [Switch to CMO] button that POSTs to
  /api/profile/switch {name: "cmo-planb"} and reloads on success
- Adds _fetchActiveProfile() that reads /api/profile/active directly
  (defense against window.S race); cached in NS.state._fetchedProfile
- Background poll every 5s catches profile switches made from the upstream
  Profiles panel — no hard reload needed to clear the banner
- Disabled-state refresh fires once on mount + on each poll

Karpathy 4 rules: smallest possible change (one button + one fetch helper),
no abstraction layer, no fallback "smart" detection — authoritative API only.
2026-05-24 13:38:39 -04:00
Svrnty
849dd27119 feat(adwright panel): add cross-link button to BTE Command Center
Some checks failed
plugin-tests / test (push) Failing after 6s
Header now shows ↗ BTE button next to the profile status pill. Click
invokes window.SvrntyBTE.open() to surface the BTE overlay, satisfying
the "Adwright pulls content from BTE panel" integration goal at the UX
level. Asset-URL-level integration follows automatically once cycles
contain BTE-rendered asset references (post Phase 8).

Themed via existing CSS vars (--accent, --border2, --accent-bg, etc) —
zero hardcoded colors. CONNECTION-MAP regenerated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:19:17 -04:00
Svrnty
0b19fdd7d0 feat(plugin): Adwright + BTE Command Center panels (v0.4.0)
Some checks failed
plugin-tests / test (push) Failing after 5s
Two new tool panels surfaced inside hermes-webui via inject_script/
inject_stylesheet. Both vanilla JS + CSS, no frameworks, WebUI CSS-vars
only (no hardcoded colors), light/dark inherits free.

## Adwright panel (static/adwright.{js,css} + routes/adwright.py)

5 tabs: Overview · Cycles · Audience · Targeting · Connections.
Layout: 60/40 panel/chat split via CSS :has() selector.
Always-visible, soft-disabled when active profile isn't `cmo*`.

Action wiring (READ path — agent-mediated per governance):
1. Panel button → fires custom event
2. Handler synthesizes /adwright <cmd> chat message
3. Posts via existing btnSend pathway → message visible in chat
4. CMO sees + calls mcp_adwright_<tool>
5. Panel polls /api/adwright/last-panel-update for structured payload
6. Mock payload returned v1; real session-DB reader plugs in when
   adwright-mcp gains writer

Connections WRITE path (governance exception, NO secrets in chat):
- POST /api/adwright/provision-creds with form fields
- Plugin invokes credctl set <key> via stdin (value never on argv)
- Allowlist enforced (defense-in-depth on key names)
- Auth-gated by WebUI session cookie

Skin: .svrnty-aw-* class prefix, window.SvrntyAdwright JS namespace,
guard against double-load, scoped MutationObserver.

## BTE Command Center panel (static/bte.{js,css} + routes/bte_proxy.py)

Content-mode pills (Polished/UGC/Photorealistic/Artistic) × media toggle
(Image/Video — Video disabled v1 pending Phase 4e) × recipe family picker
(Hero Shot/Lifestyle Shot/Photoshoot/Recipe Sheet/Montage Catalog) per
canonical PLANB-RECIPE-TAXONOMY. SKU picker, variant stepper 1-12,
single/batch toggle, [Generate] button.

Asset grid with streaming thumbnails, asset detail (full-res + rate +
comment + "Use in Adwright cycle" deep link). Embedded CMO chat right rail
for re-orienting generations ("make next batch warmer / less white space").

BTE proxy route (/api/bte/proxy) with whitelisted paths
(requestPhotoshoot, assetGrid, recipeStats, assets/{id}/thumb, etc.)
prevents browser-side CORS to BTE :6001.

Skin: .svrnty-bte-* class prefix, window.SvrntyBTE JS namespace.

## Wiring

manifest_version: 0.2.0 → 0.4.0
assets registered:
- /plugins/svrnty/adwright.{js,css} + static/adwright/
- /plugins/svrnty/bte.{js,css} + static/bte/
routes registered:
- GET /api/adwright/last-panel-update (panel update channel)
- POST /api/adwright/provision-creds (governance-exception write)
- GET/POST /api/bte/proxy (BTE REST proxy with allowlist)

Karpathy 4 rules: agents reported every deviation with rationale (Python
venv interp for hermes mcp add, missing aggregate connections-status RPC
composed from two verifies, mock panel-update v1 with locked frontend
protocol so real session-DB reader is a drop-in swap), verified asset
serving + plugin route registration before claiming complete, surfaced
open questions instead of silently choosing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:12:27 -04:00