docs: bilingual credentials/settings-consumer documentation, catalogs, and gates

New credentials data-structure page (type-equiv manifested), group README,
rewritten llm-deepseek/llm-pi-ai READMEs (dynamic configuration, dict
profiles, credential chain), capability-seams/service-role registration,
Agent Note (bilingual), demo compositions mounting settings-local +
credentials-local with no inline key plumbing, installSettingsSection
consumer helper on the settings seam (deduplicating both adapters' wiring),
jscpd symmetry markers for the provider twins, runtime-closure additions for
python/sdk-runtime, and doc-budget ceilings AGENTS.md 1750→1755 /
packages/README.md 850→865 for the structural one-line group rows.
This commit is contained in:
Yichen Jiang
2026-07-29 14:20:06 +08:00
parent d77db29f01
commit b0a2011d95
61 changed files with 732 additions and 153 deletions
+50
View File
@@ -442,4 +442,54 @@ export abstract class Settings extends Service {
}
}
/** Hooks a consumer hands to {@link installSettingsSection}. */
export interface SettingsSectionHooks<T> {
/**
* Receive the active configuration source: the resolved settings scope
* while one is attached, the composition entry otherwise. Called before
* the matching `onChange` at attach and at detach.
* @param current - thunk returning the currently authoritative value.
*/
setSource(current: () => T): void
/**
* Re-judge anything derived from the source — registration-level facts,
* memoized resolutions — after an attach, a detach, or a committed change.
*/
onChange(): void
}
/**
* Install the canonical optional-settings consumer wiring: while a settings
* service exists, register `ns` with the consumer's composition entry as the
* `base` layer and point the source thunk at the resolved scope; when the
* service goes away (disposal, provider reload), fall back to the entry so
* the consumer keeps working exactly as composed. The registration rides the
* scoped fiber, so no settings service ever mounted means none of this runs.
* @param ctx - consumer plugin context owning the wiring.
* @param ns - the consumer-owned settings namespace.
* @param schema - schema resolving the namespace (typically the plugin Config).
* @param entry - the consumer's composition entry config, used as `base`.
* @param hooks - source sink and change notification.
*/
export function installSettingsSection<T>(
ctx: Context,
ns: SettingsNamespace,
schema: z<T>,
entry: T,
hooks: SettingsSectionHooks<T>,
): void {
ctx.inject(['settings'], (sctx) => {
const scope = sctx.settings.register(ns, schema, { base: entry })
hooks.setSource(() => scope.get())
sctx.effect(() => () => {
hooks.setSource(() => entry)
hooks.onChange()
})
hooks.onChange()
scope.watch(() => {
hooks.onChange()
})
})
}
export default Settings