fix!: restore the settings page against the harness 0.1.7 plugin contracts
The configuration page registered into seats that 0.1.7 removed, so it could
not appear at all — and the schema carried none of the metadata the new
settings document requires.
Host half. `ctx.settings.installSection` no longer exists: a plugin exports a
`Config` schema, the Harness keys one form per composed entry by that row's
`id`, and `ctx.settings.describe` skips an entry with no `volatile()` field
outright. Every field is now volatile, which is also what makes a saved edit
apply to the running instance instead of remounting it — so `apply` reads the
section through `settingsSnapshot`, which unwraps the live references a
volatile field arrives as. Writes go through `ctx.settings.update` fenced by
the revision `describe` reports. The `.min`/`.max` bounds the schema can state
are stated there, so the form refuses an impossible draft in front of the
person typing it; `validateSettings` keeps the cross-field rules no single
field can express, and now runs on the section a call is about to act on
rather than at write time, because 0.1.7 has no write-time validator hook.
Browser half. `settingsScope` and the `settings.plugin.item` slot are gone. The
page renders through `plugins.row.config`, keyed `<bundle package>#<row id>`
(`dsh-recall#dsh-recall`), which is what puts a Configure control on the
plugin's row in the Plugins panel. It uses the framework's own staged form —
`SettingsFormModel` over `ctx.configForms`, drawn by `SettingsForm` and
`SettingsValueField`/`SettingsSecretField` — instead of reproducing card chrome
by hand, so the unsaved, overridden, invalid, and save states come from the
same code as every other plugin's page. All 33 settings are editable now; the
old card exposed 23. The right-sidebar tab also needed the stage-one tab TYPE
(`ctx.sidebarRightTabs.register`) that its keyed body slot is dispatched under,
so a tab can finally be opened. `--dsh-border`, defined nowhere, becomes the
product's `--dsw-alias-border-l2`.
Both halves are now pinned by tests: every field is volatile, the field list
and the schema cannot drift, the page claims the key the patch declares, and a
blank API key is never written — the secret control reports configured-and-
absent instead.
Verified against the harness rather than only in unit tests: `--dump-config-
schema` emits the volatile and secret metadata, `apply` registers `recall` on
the real tool registry, `settings.describe({redactSecrets:true})` serves
`dsh-recall` with 33 fields and the key reported set-but-redacted, and a
scratch profile boots the web app with the plugin composed and its bundle
served byte-for-byte as this checkout has it.
This commit is contained in:
1 parent
0964819cdc
commit
040c69b57d
7 files changed
+1352
-668
No files matched your search
@@ -65,17 +65,29 @@ a fact:
|
||||
embeddingApiBase: http://10.50.1.2:11434
|
||||
```
|
||||
|
||||
Or edit every setting from the UI. The plugin ships **two halves**, and the settings
|
||||
page draws a card only when it has both:
|
||||
Or edit every setting from the UI: **Plugins → dsh-recall → Configure**. The
|
||||
plugin ships **two halves**, and the page appears only when both are present and
|
||||
the deployment serves the namespace:
|
||||
|
||||
- the **host half** (`index.js`) serves a `dsh-recall` settings namespace;
|
||||
- the **browser half** (`client/client.js`) claims that same namespace with a
|
||||
collapsible card under **Settings → Plugins → Plugin configuration**.
|
||||
- the **host half** (`index.js`) exports a `Config` schema whose every field is
|
||||
`.volatile()`. That schema *is* the settings page's description — the Harness
|
||||
keys one form per profile entry by that row's `id` (`dsh-recall` in
|
||||
`cordis.patch.yml`), and it skips an entry with no volatile field entirely, so
|
||||
a schema without those markers has no settings surface at all rather than an
|
||||
empty one;
|
||||
- the **browser half** (`client/client.js`) renders that form into the Plugins
|
||||
panel's per-row configuration seat, `plugins.row.config`, keyed
|
||||
`<bundle package>#<row id>` — here `dsh-recall#dsh-recall`. Registering it is
|
||||
what adds the **Configure** control to the plugin's row.
|
||||
|
||||
A served namespace with no card renders nothing at all, and a card whose namespace
|
||||
is not served is never dispatched — so both are required. A restart is needed for a
|
||||
newly installed browser half to appear, because client bundle bytes are snapshotted
|
||||
when the profile activates.
|
||||
A served namespace with no page draws no control, and a page whose namespace is
|
||||
not served is deliberately not registered — so both are required. A restart is
|
||||
needed for a newly installed browser half to appear, because client bundle bytes
|
||||
are snapshotted when the profile activates.
|
||||
|
||||
Editing in the UI writes to the profile's own patch layer through the settings
|
||||
document, so the value survives a restart and stays visible in
|
||||
`cordis.patch.yml`.
|
||||
|
||||
Every value is also checkable from the tool, without touching a file:
|
||||
|
||||
@@ -83,9 +95,9 @@ Every value is also checkable from the tool, without touching a file:
|
||||
recall action=configure config={"embeddingApiBase":"http://10.50.1.2:11434"}
|
||||
```
|
||||
|
||||
The API key is declared `role('secret')` on the host, so it is stripped from every
|
||||
settings response — the card can show that a key is set without ever receiving it,
|
||||
and leaving it blank on save means "unchanged" rather than "clear".
|
||||
The API key is declared `role('secret')`, so it is stripped from every settings
|
||||
response: the page can show that a key is set without ever receiving it, and a
|
||||
blank draft writes nothing — leaving it alone means "unchanged", never "clear".
|
||||
|
||||
Pull the model once:
|
||||
|
||||
@@ -102,7 +114,7 @@ ollama pull unclemusclez/jina-embeddings-v2-base-code
|
||||
| `search` *(default)* | answers `query`, warming a bounded slice of the index first |
|
||||
| `index` | builds or refreshes the whole index; **background job by default** |
|
||||
| `status` | index and endpoint state, touching nothing |
|
||||
| `configure` | writes settings through the settings namespace |
|
||||
| `configure` | writes settings through the settings document |
|
||||
|
||||
Parameters: `query`, `action`, `limit`, `path` (restrict to a subdirectory),
|
||||
`run_in_background`.
|
||||
@@ -363,10 +375,16 @@ exactly that during development.
|
||||
`test/config.test.js` covers the load-time contract. Cordis rejects a `Config`
|
||||
before `apply` ever runs, so a broken schema cannot be reported from inside the
|
||||
plugin — the profile simply refuses to boot. Every other test in the suite calls
|
||||
`apply` directly and would not notice.
|
||||
`apply` directly and would not notice. It also pins the second half of that
|
||||
contract: that every field is `volatile()`, because that marker is what makes
|
||||
the Harness serve a settings page at all, and its absence is invisible from
|
||||
inside the process.
|
||||
|
||||
`test/client.test.js` runs the browser half in Node by stubbing `window` and
|
||||
`require('react')`. That is worth more than it sounds: the two failure modes most
|
||||
likely to reach you silently are structural — a root element that is not an `<li>`,
|
||||
and a card that does not start collapsed — and both are invisible until someone
|
||||
opens Settings. It also pins that an untouched API key is never written or unset.
|
||||
`test/client.test.js` runs the browser half in Node by stubbing `window`,
|
||||
`require('react')`, and the settings-form primitives. That is worth more than it
|
||||
sounds: the failure modes most likely to reach you silently are structural — a
|
||||
page registered into a slot nobody declares (which is what the 0.1.5 seat,
|
||||
`settings.plugin.item`, became), a right-sidebar body with no tab type behind it,
|
||||
and a field list that has drifted from the schema — and all three are invisible
|
||||
until someone opens Plugins. It also pins that an untouched API key is never
|
||||
written, and that the field list and `Config` name the same settings.
|
||||
Reference in new issue
Block a user