Second review round on the contained-group composition:
- Ownership scanned only `insert` rows, so an external bundle could set a
built-in row's id as a child through `{ id: own, config: [...] }` and the
Loader re-parented that row under the bundle while `originOf` still named
the built-in layer. The rows an id-targeted patch sets as a group's config
now count as the layer's own: an external bundle that sets an id another
layer owns is left out whole, a built-in layer that takes another layer's
id fails loud, and a layer restating its own child is not a repeat.
- `recompose` read the committed profile before awaiting the update, so a
watcher firing while a bundle was being enabled composed the tree before
the enable and applied it after; the plugin vanished while `layers` kept
listing it. Recompositions now queue, each reading what the previous one
committed, and a rejection stays its own caller's outcome.
- A patch that replaced a built-in target's config removed the wrapper the
bundle had put there, yet later inserts still targeted the detached
wrapper and vanished. The composition forgets the wrapper on such an
override and creates a new one under the same id.
- Generated wrapper ids bypassed the duplicate check, so a bundle declaring
a row spelled like a wrapper produced two nodes with one id. Declared and
generated ids now go through one registration.
- Failure records outlived their rows when a bundle update dropped a failed
row without unmounting the group, or when a pending row sat in a plain
nested group whose id the record named. A contained group now drops the
records of rows its configuration no longer names after each update, and
the audit records every row under the contained group that isolates it.
- `applyEntryPatches` assigned override values by reference, so applying a
patch list carried a later insert's rows back into the patch object; the
vendored include now clones object-valued overrides as it does inserts.
description, kind
| description | kind |
|---|---|
| The extensions group map: model-facing tools and dual-half runners for defining, running, and removing dynamic Cordis packages, for users and maintainers navigating the group. | package-group |
packages/extensions
English | 中文
Summary
The extensions group lets a running agent modify the runtime it runs inside: the model can inspect the plugins and services loaded in the current DSH process, define a dynamic Cordis package (with a host half, a browser half, or both), run it, stop it, and remove it, and a browser panel operates every definition. Packages evolve by plugin: a plugin holds immutable package versions and can run or update between them. Definitions live only in process memory, so a DSH restart clears them and nothing here writes repository files or configuration. Four packages form the subsystem: the model-facing tools plus the host runner, and the browser runner plus the browser UI.
Table of Contents
Packages
| Package | Role | ctx key |
|---|---|---|
tool-cordis |
Seven model-facing tools: inspect the live runtime, define, run, stop, and remove dynamic packages | registers on ctx.tools |
cordis-host-runner |
Host half: definition registry, sandboxed host-half lifecycle, and the inspect registry browser queries answer | provides ctx.dynamicCordisRunner and ctx.cordisInspect |
cordis-client-runner |
Browser half: evaluates a browser-half source into a live plugin and answers run requests | client face; provides browser ctx.dynamicCordisRunner |
ui-cordis |
Browser surfaces: the frame-wide panel, lifecycle tool cards, and the @pluginId input source |
client face; registers slots |
Related documentation
- Extensions subsystem — the generated
ctx.cordisInspectandctx.dynamicCordisRunnerservice API. - Generated tool catalog — the seven model-facing tool schemas.
- Generated configuration catalog — the runner's accepted config fields.
- Self-referential Cordis toolset Agent Note — design home for sandbox semantics, lifecycle, and composition.
- Client shells and dynamic packages Agent Note — package placement and build faces for the client halves.
Dev Note
Working context for maintainers — click to expand
The two browser-half packages live in this group rather than under packages/client/ because they are halves of this subsystem's dual-half packages; the client face compiles them through the client program, while the host program references only the host runner.