feat(plugin-inventory): carry every agent preset's composition and group the settings plugin list by scope

The settings plugin list projected ctx.loader.entries() alone, hiding the
plugins sessions actually run and rendering the web overlay's deliberate
disabled tombstones (tool-bash, tool-fs, ...) as two dozen plainly disabled
rows while the same modules ran in every standard-preset session.

- dsh-agent-presets: compositionInventory() answers flattened rows per
  preset — newest live standing generation when mounted, composition file
  otherwise with !!js disabled gates evaluated against the Loader context;
  reading never mounts (regression-tested), refusal stays 'conditional',
  raced files report broken with the reason.
- dsh-host-plugin-inventory: list() gains an optional agentPresets block,
  resolving the roster as an optional peer and mapping fiber states to the
  public phase vocabulary.
- ui-settings-plugin-inventory: preset group first behind a display-only
  switcher opening on the default preset; global group collapsed with
  failures floated; host-disabled modules enabled by >=1 preset fold into a
  session-plugins drawer naming providers; search spans scopes and points
  at matches in unselected presets.
- ui-agent-preset: the General-settings default-preset row is deleted — the
  roster section's make-default and the new-session chip keep the field —
  and the settings store slims to the display roster the header label reads.

Docs, catalogs, module graph, settings-chrome goldens, and the bilingual
Agent Note ride along.
This commit is contained in:
Yichen Jiang
2026-08-29 17:13:45 +08:00
parent cd5ef81481
commit e5f36cc70f
52 changed files with 1769 additions and 824 deletions
+2 -2
View File
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/subsystems/core.md
core.md: dbe12dfc9bfdafe0f59d7e52eefc5695b1c8d063
core.zh.md: 50fd2e4e76ee72653c02c2ffeca06042191aa9c4
core.md: 8af708c4e12677e376bfc2adf2ff52490f5ec1a5
core.zh.md: 1680e51a9f3a0363c28b3582d8a3e5399d5b2530
+16
View File
@@ -410,6 +410,22 @@ async list(): Promise<AgentPreset[]>
*/
@Remote('list') async remoteExportList(): Promise<AgentPresetRoster>
/**
* Every preset's composition as flattened plugin rows, for plugin-listing
* surfaces beside the roster's own picker.
*
* A preset with a live standing mount answers from its newest generation's
* Loader entries — the composition new sessions join — and one never
* composed since boot answers from its file, with `!!js` disabled gates
* evaluated against the Loader context so both answers reflect the same
* host. Reading never mounts: an unmounted preset is parsed, not composed,
* so listing a preset's plugins cannot activate them early. A composition
* that stopped reading between discovery's health verdict and this read is
* reported broken with the raced reason rather than dropped.
* @returns one composition per roster preset, in roster order.
*/
async compositionInventory(): Promise<AgentPresetComposition[]>
/**
* Resolve one preset by id.
*
+16
View File
@@ -420,6 +420,22 @@ async list(): Promise<AgentPreset[]>
*/
@Remote('list') async remoteExportList(): Promise<AgentPresetRoster>
/**
* Every preset's composition as flattened plugin rows, for plugin-listing
* surfaces beside the roster's own picker.
*
* A preset with a live standing mount answers from its newest generation's
* Loader entries — the composition new sessions join — and one never
* composed since boot answers from its file, with `!!js` disabled gates
* evaluated against the Loader context so both answers reflect the same
* host. Reading never mounts: an unmounted preset is parsed, not composed,
* so listing a preset's plugins cannot activate them early. A composition
* that stopped reading between discovery's health verdict and this read is
* reported broken with the raced reason rather than dropped.
* @returns one composition per roster preset, in roster order.
*/
async compositionInventory(): Promise<AgentPresetComposition[]>
/**
* Resolve one preset by id.
*