fix(client-ui-plugin-config): refresh the key badge when the Host reports the credential changed

The card read the credential only when its settings scope published, and a
credential is not part of any settings section: a key written from the Models
page — which addresses the same reference — left this badge reporting a state
the Host had already replaced. It now re-reads on credentials/changed for the
reference it watches, and ignores the event for any other reference.
This commit is contained in:
Yichen Jiang
2026-08-11 18:00:24 +08:00
parent aa6abf218c
commit 3c8cf3a564
7 changed files with 81 additions and 4 deletions

View File

@@ -55,6 +55,14 @@ export function apply(ctx: ClientContext): void {
const agentLoop = new AgentLoopCardController(bindSettingsScope(ctx, { namespace: AGENT_LOOP_NS }))
const webSearch = new WebSearchCardController(bindSettingsScope(ctx, { namespace: WEB_SEARCH_NS }), api)
// The credential a card reports is not part of any settings section, so its
// scope publishes nothing when one is written. This is the only signal that
// a key written on another surface reached the Host.
ctx.effect(
() => ctx.on('credentials/changed', (ref) => { webSearch.refreshCredential(ref) }),
'ui-plugin-config: credential invalidations',
)
// The section renders the empty line rather than an empty list when no plugin
// contributed a card. The count is read once: the renderer caches a root
// entry's inject face per registration, so this reports what was registered

View File

@@ -143,6 +143,19 @@ export class WebSearchCardController {
this.store.set(this.projection())
}
/**
* Re-read after the Host reports a change to the reference this card watches.
*
* A key can be written from somewhere else — the Models page addresses the
* same reference — and the settings section does not change when it is, so
* without this the badge keeps reporting a state the Host already replaced.
* @param ref - the reference the Host reports as changed.
*/
refreshCredential(ref: string): void {
if (ref !== this.credential.ref) return
void this.readCredential()
}
/**
* Build the face the card's slot registration injects.
* @returns the card's snapshot and its form actions.