dsh-connect 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +119 -18
- package/README.zh.md +87 -13
- package/client/client.js +18 -15
- package/client/client.js.map +2 -2
- package/client/settings-client.mjs +22 -13
- package/lib/channels/dingtalk/index.d.ts +49 -49
- package/lib/channels/dingtalk/index.d.ts.map +1 -1
- package/lib/channels/feishu/adapter.d.ts +8 -1
- package/lib/channels/feishu/adapter.d.ts.map +1 -1
- package/lib/channels/feishu/adapter.js +120 -39
- package/lib/channels/feishu/adapter.js.map +1 -1
- package/lib/channels/feishu/index.d.ts +27 -27
- package/lib/channels/feishu/index.d.ts.map +1 -1
- package/lib/channels/telegram/index.d.ts +13 -13
- package/lib/channels/telegram/index.d.ts.map +1 -1
- package/lib/channels/web/adapter.d.ts +3 -1
- package/lib/channels/web/adapter.d.ts.map +1 -1
- package/lib/channels/web/adapter.js +3 -1
- package/lib/channels/web/adapter.js.map +1 -1
- package/lib/channels/web/index.d.ts +5 -5
- package/lib/channels/web/index.d.ts.map +1 -1
- package/lib/index.d.ts +42 -58
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +162 -57
- package/lib/index.js.map +1 -1
- package/lib/interaction.d.ts +90 -50
- package/lib/interaction.d.ts.map +1 -1
- package/lib/interaction.js +233 -272
- package/lib/interaction.js.map +1 -1
- package/lib/retry.d.ts.map +1 -1
- package/lib/retry.js +7 -1
- package/lib/retry.js.map +1 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +0 -2
- package/lib/service.js.map +1 -1
- package/lib/settings/legacy-import.d.ts +190 -0
- package/lib/settings/legacy-import.d.ts.map +1 -0
- package/lib/settings/legacy-import.js +373 -0
- package/lib/settings/legacy-import.js.map +1 -0
- package/lib/settings/namespace.d.ts +204 -116
- package/lib/settings/namespace.d.ts.map +1 -1
- package/lib/settings/namespace.js +235 -148
- package/lib/settings/namespace.js.map +1 -1
- package/lib/settings/settings-model.d.ts.map +1 -1
- package/lib/settings/settings-model.js +10 -1
- package/lib/settings/settings-model.js.map +1 -1
- package/lib/settings/settings-service.d.ts +13 -0
- package/lib/settings/settings-service.d.ts.map +1 -1
- package/lib/settings/settings-service.js +73 -4
- package/lib/settings/settings-service.js.map +1 -1
- package/lib/types.d.ts +14 -1
- package/lib/types.d.ts.map +1 -1
- package/package.json +12 -11
|
@@ -1,55 +1,130 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `dsh-connect` user-settings
|
|
2
|
+
* The `dsh-connect` user-settings seam.
|
|
3
3
|
*
|
|
4
|
-
* DSH
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* provider, and `scope.watch()` tells the plugin to re-read.
|
|
4
|
+
* DSH 0.2 replaced the plugin-facing settings API. The old `ctx.settings`
|
|
5
|
+
* namespace contract (`installSection(owner, ns, schema, entry, hooks)` backed by
|
|
6
|
+
* a `$DSH_HOME/settings.yaml` section keyed by the plugin *name*) is gone; what
|
|
7
|
+
* is left is `SettingsForms`, which edits a plugin's **profile entry** and
|
|
8
|
+
* hot-commits the fields that plugin declared `volatile`:
|
|
10
9
|
*
|
|
11
|
-
*
|
|
10
|
+
* - **Reads come from our own config.** A field declared with
|
|
11
|
+
* `z.…volatile()` arrives in `apply()` as a *reference* (`{ get() }`) rather
|
|
12
|
+
* than a value, and the loader updates that reference in place when the
|
|
13
|
+
* profile entry changes — no remount, no `apply()` re-entry. So there is no
|
|
14
|
+
* read API to call: the live state is `refs.get()`, and this module's
|
|
15
|
+
* `materializeConfig()` turns the ref-carrying config into a plain snapshot.
|
|
16
|
+
* - **Writes go through `SettingsForms.replace(ns, section)`**, where `ns` is
|
|
17
|
+
* the profile entry id (`connect`) — *not* the package name. `replace` resets
|
|
18
|
+
* every live field to its inherited value and then applies the supplied ones,
|
|
19
|
+
* which is exactly "this is the user's complete visible config" — and why a
|
|
20
|
+
* *partial* section is a destructive write: a field the caller omits is
|
|
21
|
+
* reset, not preserved. Callers that mean to preserve something must merge
|
|
22
|
+
* it in first ({@link mergeSections}).
|
|
23
|
+
* - **`volatileForm(schema)` must not be empty**, or `replace` refuses the
|
|
24
|
+
* write with `Plugin entry "connect" has no volatile fields`. That is why
|
|
25
|
+
* `paneConfigFields()` exists and must keep declaring the pane's field set.
|
|
12
26
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* `settings.yaml` with a typo must degrade to the plugin config, not abort
|
|
22
|
-
* the plugin's `apply`.
|
|
27
|
+
* **Only volatile *leaves* may be declared — never a volatile container.**
|
|
28
|
+
* `projectForm(form, base)` projects the *base* layer down to volatile fields
|
|
29
|
+
* before the write is merged: if `feishu` itself were volatile it would be
|
|
30
|
+
* copied whole into the settings document, `appSecret` and all. Declaring the
|
|
31
|
+
* leaves keeps every non-pane key (`appSecret`, `appId`, …) in the raw
|
|
32
|
+
* remainder, where `strip()` leaves ordinary config untouched. This is the same
|
|
33
|
+
* hazard `sectionOf()` guards on the write path, from the other side: an
|
|
34
|
+
* undeclared key in a *submitted* section must not reach the document either.
|
|
23
35
|
*
|
|
24
|
-
*
|
|
25
|
-
* credential store (`ctx.credentials`), which is where
|
|
26
|
-
*
|
|
27
|
-
* plain
|
|
28
|
-
* projects secret keys *out* of the base for the same reason — schemastery
|
|
29
|
-
* preserves undeclared keys verbatim, so anything left in the base rides out
|
|
30
|
-
* through `describe()` and the settings RPC. The same projection guards the
|
|
31
|
-
* write path (`LiveConnectSection.write`), which is the mirror hazard: an
|
|
32
|
-
* undeclared key in a *submitted* section would be preserved into the document.
|
|
33
|
-
*
|
|
34
|
-
* `installSection` returns nothing, so the write handle it hands back is built
|
|
35
|
-
* here: `setSource` already wires a thunk onto `scope.get()`, which reads the
|
|
36
|
-
* registration's resolved value at call time — live in both directions.
|
|
36
|
+
* Secrets therefore never appear in either declared surface: they live in the
|
|
37
|
+
* DSH credential store (`ctx.credentials`), which is where onboarding and the
|
|
38
|
+
* `FEISHU_*`-style env layering already put them, and `settings`-side documents
|
|
39
|
+
* are plain files users are invited to paste into bug reports.
|
|
37
40
|
*
|
|
38
41
|
* @module dsh-connect/settings/namespace
|
|
39
42
|
*/
|
|
40
43
|
import z from "@deepseek-ai/schemastery";
|
|
41
|
-
import { type ChannelName, type
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
+
import { type ChannelName, type LoggerLike } from "./channels.js";
|
|
45
|
+
/**
|
|
46
|
+
* The section key the pre-0.2 harness read from `$DSH_HOME/settings.yaml`, keyed
|
|
47
|
+
* by plugin *name*. Nothing writes it any more; `legacy-import.ts` reads it once
|
|
48
|
+
* so an upgrading user's pane settings survive the switch to the new store.
|
|
49
|
+
*/
|
|
50
|
+
export declare const LEGACY_CONNECT_SECTION = "dsh-connect";
|
|
51
|
+
/**
|
|
52
|
+
* The automatic-page policy for our entry. `auto: false` stops the host's
|
|
53
|
+
* Plugins page from generating a second, generic form for `connect`: this
|
|
54
|
+
* plugin ships its own client pane (`client/settings-client.mjs`), and two
|
|
55
|
+
* editors writing the same fields through different UIs is how a save silently
|
|
56
|
+
* reverts. Register it with `settings.configure(policy, ctx.fiber)` — the
|
|
57
|
+
* `owner` argument matters, see `index.ts`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const CONNECT_PRESENTATION: Record<string, unknown>;
|
|
60
|
+
/** A config reference: a stable handle whose value the loader replaces in place. */
|
|
61
|
+
export interface ConfigRef<T = unknown> {
|
|
62
|
+
/** The current immutable snapshot; `undefined` for a field absent from the config. */
|
|
63
|
+
get(): T;
|
|
64
|
+
}
|
|
65
|
+
/** Whether a parsed config value is a volatile reference rather than plain data. */
|
|
66
|
+
export declare function isConfigRef(value: unknown): value is ConfigRef;
|
|
67
|
+
/**
|
|
68
|
+
* Copy a ref-carrying config into plain data: every reference replaced by its
|
|
69
|
+
* current snapshot, recursively, so callers can hand the result to code that
|
|
70
|
+
* only understands plain objects (the adapters, the settings pane, tests).
|
|
71
|
+
*
|
|
72
|
+
* The copy is *fresh* rather than the snapshot itself, deliberately: snapshots
|
|
73
|
+
* are deeply frozen, and both `ChannelRuntime` (which spreads a channel's
|
|
74
|
+
* config into a new object) and the pane (which holds a form to edit) want
|
|
75
|
+
* mutable data. Cycles in ordinary config are tolerated via `seen`; a snapshot
|
|
76
|
+
* cannot contain references (the loader commits plain data), but the walk
|
|
77
|
+
* treats them uniformly so it does not matter.
|
|
78
|
+
*
|
|
79
|
+
* **A key that materializes to `undefined` is dropped, not copied.** Every
|
|
80
|
+
* declared volatile leaf is present in the parsed config even when the profile
|
|
81
|
+
* never set it — `z.object({transport: z.any().volatile()})` resolves an absent
|
|
82
|
+
* `transport` to a reference to `undefined` — so a faithful copy would hand the
|
|
83
|
+
* adapters `{transport: undefined, language: undefined, …}`. That is not the
|
|
84
|
+
* same as absent: `ChannelRuntime` resolves a channel as
|
|
85
|
+
* `{...channelDefaults, ...overrides}`, and since `language` is a key of *both*
|
|
86
|
+
* tables, a channel's own `language: undefined` would mask the shared
|
|
87
|
+
* `channelDefaults.language` every other channel still gets. Config here is
|
|
88
|
+
* JSON-shaped (a profile entry, a YAML document, the settings RPC), where
|
|
89
|
+
* `undefined` can only ever mean "this key was not set", so dropping it restores
|
|
90
|
+
* exactly the shape a plain `z.any()` field used to produce.
|
|
91
|
+
*/
|
|
92
|
+
export declare function materializeConfig<T>(value: T): T;
|
|
93
|
+
/**
|
|
94
|
+
* The volatile half of the plugin `Config`, derived from the same field tables
|
|
95
|
+
* the settings pane renders. Deriving rather than restating them is the point:
|
|
96
|
+
* a field added to `CHANNEL_CONFIG_FIELDS` becomes user-editable *and*
|
|
97
|
+
* hot-appliable in one edit, and a field the pane offers can never be missing
|
|
98
|
+
* from the schema (a write of an undeclared path is refused by the host).
|
|
99
|
+
*
|
|
100
|
+
* Every leaf is `z.any()` on purpose. A stricter node would let a stale value
|
|
101
|
+
* in a profile — a `webhookPort` written as a string, a `dmMode` from a version
|
|
102
|
+
* that spelled it differently — abort config validation and keep the bridge
|
|
103
|
+
* from loading at all. The pane's own `coerceConfigValue` is what keeps types
|
|
104
|
+
* honest; the schema's job here is only to say "these paths are live-editable".
|
|
105
|
+
*
|
|
106
|
+
* `channels` is a loose `z.array(z.string())` for the same reason, and it is
|
|
107
|
+
* safe because `ChannelRuntime` skips a name it has no adapter for (with a log
|
|
108
|
+
* line) instead of throwing. Its explicit `.default([...CHANNELS])` is load
|
|
109
|
+
* bearing, not cosmetic: a volatile *array* resolves an absent key to `[]`
|
|
110
|
+
* rather than `undefined`, so a profile that never set `channels` would
|
|
111
|
+
* otherwise materialize an empty list and start no adapter at all, where the
|
|
112
|
+
* documented default — and the pre-volatile behaviour — is every channel. A
|
|
113
|
+
* default also keeps `replace()`'s reset target honest: an omitted `channels`
|
|
114
|
+
* in a section resets to all channels, not to none. `[...CHANNELS]` rather than
|
|
115
|
+
* `CHANNELS` so the schema cannot hand out the module's own array.
|
|
116
|
+
*/
|
|
117
|
+
export declare function paneConfigFields(): Record<string, z<any>>;
|
|
44
118
|
/** Channel-agnostic defaults section of the namespace. */
|
|
45
119
|
export type ConnectSectionDefaults = Record<string, unknown> & {
|
|
46
120
|
language?: string;
|
|
47
121
|
notifyLevel?: string;
|
|
48
122
|
};
|
|
49
123
|
/**
|
|
50
|
-
* The
|
|
51
|
-
*
|
|
52
|
-
*
|
|
124
|
+
* The pane-editable slice of the config: the whole of what this plugin stores
|
|
125
|
+
* on the user's behalf. Every field is optional — a user who only ever edits
|
|
126
|
+
* `channels` leaves the rest absent, and each adapter applies its own default
|
|
127
|
+
* for anything missing.
|
|
53
128
|
*/
|
|
54
129
|
export interface ConnectSection {
|
|
55
130
|
channels?: ChannelName[];
|
|
@@ -59,117 +134,130 @@ export interface ConnectSection {
|
|
|
59
134
|
dingtalk?: Record<string, unknown>;
|
|
60
135
|
web?: Record<string, unknown>;
|
|
61
136
|
}
|
|
137
|
+
export interface SectionOptions {
|
|
138
|
+
/**
|
|
139
|
+
* Materialize `channels` even when the source omits the key. True (the
|
|
140
|
+
* default) for the *write* path: there an absent key means "the caller did
|
|
141
|
+
* not speak to the channel list", and a section without `channels` handed to
|
|
142
|
+
* `replace()` is a reset — reading it as "activate nothing" would switch
|
|
143
|
+
* every adapter off. False for the legacy import, where an absent key must
|
|
144
|
+
* stay absent so the profile's own `channels` keeps applying.
|
|
145
|
+
*
|
|
146
|
+
* Note this is about the *key being absent*, not about an empty array: a user
|
|
147
|
+
* who unchecks every channel saves `channels: []`, which is an explicit
|
|
148
|
+
* "none" and is left alone.
|
|
149
|
+
*/
|
|
150
|
+
defaultChannels?: boolean;
|
|
151
|
+
}
|
|
62
152
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
153
|
+
* Project a config onto the pane's field set: declared, non-secret keys only.
|
|
154
|
+
*
|
|
155
|
+
* Two callers, one guard. For a **read** the input is a materialized snapshot
|
|
156
|
+
* of our own config (a profile may legitimately carry `appSecret`, and it must
|
|
157
|
+
* not travel out through the snapshot the pane receives); for a **write** the
|
|
158
|
+
* input is untrusted JSON from the settings RPC, and an undeclared key would
|
|
159
|
+
* otherwise be preserved into the profile by schemastery's passthrough. Both
|
|
160
|
+
* are the same projection, so both get the same answer.
|
|
68
161
|
*
|
|
69
|
-
* `
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
162
|
+
* `channels` is emitted unconditionally on the write path because an absent
|
|
163
|
+
* array resolves to `[]` (schemastery's array default), which would read as
|
|
164
|
+
* "activate nothing". Unknown channel names are dropped rather than refused:
|
|
165
|
+
* a name this version does not know is not a reason to reject the whole save.
|
|
73
166
|
*/
|
|
74
|
-
export declare
|
|
75
|
-
channels: z<ChannelName[], ChannelName[]>;
|
|
76
|
-
channelDefaults: z<any, any>;
|
|
77
|
-
feishu: z<any, any>;
|
|
78
|
-
telegram: z<any, any>;
|
|
79
|
-
dingtalk: z<any, any>;
|
|
80
|
-
web: z<any, any>;
|
|
81
|
-
}>, Schemastery.ObjectT<{
|
|
82
|
-
channels: z<ChannelName[], ChannelName[]>;
|
|
83
|
-
channelDefaults: z<any, any>;
|
|
84
|
-
feishu: z<any, any>;
|
|
85
|
-
telegram: z<any, any>;
|
|
86
|
-
dingtalk: z<any, any>;
|
|
87
|
-
web: z<any, any>;
|
|
88
|
-
}>>;
|
|
167
|
+
export declare function sectionOf(config: unknown, options?: SectionOptions): ConnectSection;
|
|
89
168
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* `channels` is emitted unconditionally because an absent array resolves to
|
|
94
|
-
* `[]` (schemastery's array default), which would read as "activate nothing".
|
|
169
|
+
* Layer one section over another: for each channel and for the shared defaults,
|
|
170
|
+
* the override's own keys win and the base's surviving keys are kept.
|
|
95
171
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* The argument is typed `unknown` because this doubles as the *write* guard:
|
|
102
|
-
* a section submitted through the settings RPC is untrusted JSON, and it must
|
|
103
|
-
* go through the same projection before it can reach the document.
|
|
172
|
+
* This exists because of how `replace()` treats an omission — see the module
|
|
173
|
+
* doc. A caller that has a section in force and only wants to change part of it
|
|
174
|
+
* must merge, never pass the part alone: `feishu: { transport }` resets every
|
|
175
|
+
* other declared `feishu` field, and a section without `channels` resets the
|
|
176
|
+
* channel list itself, which switches every adapter off.
|
|
104
177
|
*/
|
|
105
|
-
export declare function
|
|
178
|
+
export declare function mergeSections(base: ConnectSection, override: ConnectSection): ConnectSection;
|
|
106
179
|
/**
|
|
107
|
-
* The slice of
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
180
|
+
* The slice of `SettingsForms` this module calls. Declared structurally so the
|
|
181
|
+
* plugin keeps no dependency on `@deepseek-ai/dsh-settings` (a `dsh-base` row we
|
|
182
|
+
* cannot import at build time): a missing method degrades to "no live store"
|
|
183
|
+
* rather than a crash, and the settings service falls back to its JSON file.
|
|
111
184
|
*/
|
|
112
185
|
export interface SettingsProviderLike {
|
|
113
|
-
installSection?(owner: unknown, ns: string, schema: unknown, entry: unknown, hooks: {
|
|
114
|
-
setSource: (source: () => unknown) => void;
|
|
115
|
-
onChange: () => void;
|
|
116
|
-
}): void;
|
|
117
|
-
/** Resolved value of a registered namespace, `undefined` while unregistered. */
|
|
118
|
-
get?(ns: string): unknown;
|
|
119
186
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
187
|
+
* Register this plugin instance's page policy. `owner` must be the plugin's
|
|
188
|
+
* own fiber — the default is the *service's* fiber, which would make the
|
|
189
|
+
* policy invisible to this instance's page and leak on every reload.
|
|
190
|
+
* @returns Disposer; register it with the plugin's effects.
|
|
191
|
+
*/
|
|
192
|
+
configure?(presentation: Record<string, unknown>, owner?: unknown): () => void;
|
|
193
|
+
/**
|
|
194
|
+
* Reset every live field to its inherited value, then apply `section`;
|
|
195
|
+
* ordinary (non-live) config is preserved.
|
|
123
196
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* schema), so a replace cannot drop anything either surface can produce.
|
|
197
|
+
* `expectedRevision` is deliberately omitted by every caller here: `write`
|
|
198
|
+
* only enforces the revision check when it is defined, and we read our state
|
|
199
|
+
* from config references rather than from `describe()`, so there is no
|
|
200
|
+
* revision to round-trip. Two concurrent editors of the pane would still both
|
|
201
|
+
* land, last write winning — the same behaviour the JSON store had.
|
|
130
202
|
*/
|
|
131
203
|
replace?(ns: string, section: unknown, expectedRevision?: number): Promise<unknown>;
|
|
132
204
|
}
|
|
133
|
-
/** A live handle onto the
|
|
205
|
+
/** A live handle onto the profile entry: read the effective section, write a new one. */
|
|
134
206
|
export interface LiveConnectSection {
|
|
135
|
-
/** The section in force right now
|
|
207
|
+
/** The section in force right now, read from the config references. */
|
|
136
208
|
read(): ConnectSection;
|
|
137
209
|
/**
|
|
138
|
-
* Replace the user's section with the declared-key projection of `config
|
|
139
|
-
*
|
|
140
|
-
*
|
|
210
|
+
* Replace the user's section with the declared-key projection of `config`,
|
|
211
|
+
* then hand the new section to `onChange`. Rejects if the host refuses the
|
|
212
|
+
* write (a non-volatile path, a missing entry) — the caller is expected to
|
|
213
|
+
* surface that rather than swallow it.
|
|
141
214
|
*/
|
|
142
215
|
write(config: unknown): Promise<void>;
|
|
143
216
|
}
|
|
144
|
-
/** Outcome of wiring the
|
|
217
|
+
/** Outcome of wiring the seam. */
|
|
145
218
|
export interface InstallConnectSectionResult {
|
|
146
|
-
/** True when
|
|
219
|
+
/** True when a write handle exists, i.e. a save can land and take effect. */
|
|
147
220
|
live: boolean;
|
|
148
|
-
/** The section in force at install time
|
|
221
|
+
/** The section in force at install time. */
|
|
149
222
|
section: ConnectSection;
|
|
150
|
-
/**
|
|
151
|
-
* Read/write onto the registration. Present only when this fiber owns a live
|
|
152
|
-
* namespace *and* the provider exposes a write method; otherwise the caller
|
|
153
|
-
* keeps its own fallback (the plugin config, or the legacy state file).
|
|
154
|
-
*/
|
|
223
|
+
/** Read/write onto the profile entry; absent when the seam is unavailable. */
|
|
155
224
|
handle?: LiveConnectSection;
|
|
156
225
|
}
|
|
157
226
|
export interface InstallConnectSectionOptions<Ctx extends LoggerLike> {
|
|
158
|
-
/**
|
|
227
|
+
/** The plugin's own context: `logger` for diagnostics, and the fallback owner. */
|
|
159
228
|
owner: Ctx;
|
|
160
229
|
settings: SettingsProviderLike | undefined;
|
|
161
|
-
/** The
|
|
162
|
-
|
|
163
|
-
/**
|
|
230
|
+
/** The ref-carrying config this plugin was applied with (see `materializeConfig`). */
|
|
231
|
+
config: unknown;
|
|
232
|
+
/** The profile entry id (`connect`), from the loader entry. */
|
|
233
|
+
ns: string | undefined;
|
|
234
|
+
/** Called with the in-force section at install and after every successful write. */
|
|
164
235
|
onChange: (section: ConnectSection) => void;
|
|
165
236
|
}
|
|
166
237
|
/**
|
|
167
|
-
*
|
|
238
|
+
* Wire the plugin's config references to the host's settings service.
|
|
168
239
|
*
|
|
169
|
-
* Never throws
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
240
|
+
* Never throws. A host without `SettingsForms`, a context where the entry id
|
|
241
|
+
* cannot be resolved (a bare unit-test context, or a plugin mounted outside the
|
|
242
|
+
* loader) and a refused `replace` all degrade to `live: false` with one warning
|
|
243
|
+
* line — a settings integration that cannot work must never be the reason a
|
|
244
|
+
* bridge fails to start.
|
|
173
245
|
*/
|
|
174
246
|
export declare function installConnectSection<Ctx extends LoggerLike>(options: InstallConnectSectionOptions<Ctx>): InstallConnectSectionResult;
|
|
247
|
+
declare module "@deepseek-ai/cordis" {
|
|
248
|
+
interface Events {
|
|
249
|
+
/**
|
|
250
|
+
* Dispatched to the owning fiber when the loader commits changed volatile
|
|
251
|
+
* config paths **in place**, without remounting the plugin — a settings-pane
|
|
252
|
+
* save, or an edit to a running profile's patch. The payload is the changed
|
|
253
|
+
* paths; a consumer re-reads the references it was applied with
|
|
254
|
+
* ({@link materializeConfig}) rather than being told the new values.
|
|
255
|
+
*
|
|
256
|
+
* Declared here because cordis's `on()` typechecks event names against this
|
|
257
|
+
* interface and nothing this plugin depends on names the event — an
|
|
258
|
+
* undeclared name would be a type error at the only call site (`index.ts`).
|
|
259
|
+
*/
|
|
260
|
+
"loader/volatile-update"(paths: readonly (readonly string[])[]): void;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
175
263
|
//# sourceMappingURL=namespace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../src/settings/namespace.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../src/settings/namespace.ts"],"names":[],"mappings":"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"}
|