Commit graph

7 commits

Author SHA1 Message Date
Tianyi Cui
3e24087bfa fix(web): authenticate the browser Host API 2026-08-25 14:23:45 +08:00
Tianyi Cui
934976732d docs: purge residual chain-of-thought leakage 2026-08-22 13:10:23 +08:00
Yichen Jiang
cf7d485b5e fix(client): harden settings describe mirror 2026-08-18 15:26:16 +08:00
Yichen Jiang
06e01b30dd Merge remote-tracking branch 'origin/master' into feat/plugin-owned-settings-surface
# Conflicts:
#	packages/client/ui-plugin-config/README.i18n.yaml
#	packages/client/ui-plugin-config/README.md
#	packages/client/ui-plugin-config/README.zh.md
#	packages/client/ui-plugin-config/src/client/PluginConfigSection.tsx
#	packages/client/ui-plugin-config/src/client/index.ts
#	packages/client/ui-plugin-config/tests/apply.client.spec.ts
#	packages/client/ui-plugin-config/tests/section.client.spec.tsx
2026-08-12 22:50:49 +08:00
Yichen Jiang
fdb1c47896 docs(settings): scope the ordering claim and record the deferred wire gaps
Card registration order is stable only for cards one package installs
together: apply order between packages is unconstrained, so several
external cards can still reorder between boots. The note and README said
otherwise. Recorded alongside it: the redactor returns a secret reachable
only through a union, intersection, or transform verbatim, and serving
every registered namespace widens that gap to third-party schemas; and
the headline capability still lacks an assembled-composition test.

publish() now keeps its snapshot reference when neither the loaded flag
nor the dispatched namespaces moved, so an unrelated settings commit no
longer re-renders the card list.
2026-08-12 21:41:23 +08:00
Yichen Jiang
5d9f026e55 fix(settings): correct the exposure analysis and satisfy the coverage and lint gates
The Agent Note claimed the plugin inventory page already exposed every
mounted plugin's effective configuration to the same browser, so the
removed allowlist blocked nothing a caller could not already read. That
is false: PluginInventoryEntry carries entryId, moduleName, enabled, and
fiberPhase, and the page's configuration row renders an enabled tag, not
a stored value. The allowlist did keep an unlisted namespace's resolved,
base, and user values off the wire; the note now says so and rests the
decision on the loopback pin, secret redaction, the user's own document,
and the fact that permission and agent-presets were already served.

The post-await disposal check reads through an opaque method, mirroring
the settings seam's isStopped(): control flow narrowed the field to false
across the await, so the lint gate saw the guard as dead.
2026-08-12 21:35:21 +08:00
Yichen Jiang
4366528a38 feat(settings): serve every registered namespace and key plugin cards on it
A plugin that registered a settings namespace could not reach the browser
configuration page: the api-proxy filtered every read and gated every
write through two hardcoded namespace lists, and the plugin configuration
section rendered an unordered list of cards carrying an opaque id rather
than the namespace they edit. Both gates lived in this repository, so a
user-authored plugin was configurable only by hand-editing settings.yaml.

The proxy now serves whatever ctx.settings.describe() returns and adds no
boundary of its own; a name no registration answers folds into the seam's
own settings-rejected, and the settings-not-exposed code retires. The
settings seam is untouched: which client may read a namespace, and which
page renders it, are facts about consumers.

settings.plugin.item becomes a keyed slot whose key is the namespace a
card edits, following tool.call.toolview. The section reads describe once
and dispatches the intersection of the slot ledger and the served set, so
a namespace another surface owns renders nothing without declaring
anything, and a card for an uncomposed plugin is never dispatched.
2026-08-12 21:07:57 +08:00