@morlay/ui-conversation-message-actions 0.0.11 → 0.0.13

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.
Files changed (42) hide show
  1. package/README.md +0 -6
  2. package/dist/client.js +831 -0
  3. package/dist/index.d.mts +105 -0
  4. package/dist/index.mjs +3 -0
  5. package/dist/invariant.d.mts +7 -0
  6. package/dist/invariant.mjs +8 -0
  7. package/dist/plan-Bw4zoI4N.d.mts +86 -0
  8. package/dist/plan.d.mts +2 -0
  9. package/dist/plan.mjs +225 -0
  10. package/dist/src-CXYW0Bc0.mjs +408 -0
  11. package/dist/testing.d.mts +707 -0
  12. package/dist/testing.mjs +23690 -0
  13. package/package.json +60 -31
  14. package/src/client/chat-node/MessageEditDialog.module.css +24 -0
  15. package/src/client/chat-node/MessageEditDialog.tsx +71 -0
  16. package/src/client/chat-node/MessageIconActions.module.css +86 -0
  17. package/src/client/chat-node/MessageIconActions.tsx +189 -0
  18. package/src/client/chat-node/MessageItem.module.css +290 -0
  19. package/src/client/chat-node/MessageItem.tsx +198 -0
  20. package/src/client/chat-node/message-chrome.ts +61 -0
  21. package/src/client/chat-node/register.ts +33 -0
  22. package/src/client/chat-node/use-calendar-day.ts +23 -0
  23. package/src/client/controller.ts +327 -0
  24. package/src/client/css-modules.d.ts +4 -0
  25. package/src/client/import-action.tsx +74 -0
  26. package/src/client/index.ts +50 -0
  27. package/src/index.ts +650 -0
  28. package/src/invariant.ts +13 -0
  29. package/src/plan.ts +322 -0
  30. package/src/shared.ts +167 -0
  31. package/src/testing.ts +151 -0
  32. package/src/types.ts +73 -0
  33. package/lib/client.js +0 -2243
  34. package/lib/client.js.map +0 -1
  35. package/lib/index.d.mts +0 -211
  36. package/lib/index.d.mts.map +0 -1
  37. package/lib/index.mjs +0 -685
  38. package/lib/index.mjs.map +0 -1
  39. package/lib/invariant.d.mts +0 -15
  40. package/lib/invariant.d.mts.map +0 -1
  41. package/lib/invariant.mjs +0 -22
  42. package/lib/invariant.mjs.map +0 -1
@@ -0,0 +1,707 @@
1
+ import { SessionEditor } from "./index.mjs";
2
+ import { Context, Service } from "@deepseek-ai/cordis";
3
+ import { BranchBoundary, BranchTimeline, SessionBranch } from "@morlay/session-branch";
4
+ import { TokenMeter } from "@deepseek-ai/dsh-token-meter";
5
+ import { Session, Session as Session$1, SessionEvent, SessionEvent as SessionEvent$1, SessionHeader, SessionHeader as SessionHeader$1, SessionId, SessionId as SessionIdBrand, SessionSeq, SessionStore } from "@deepseek-ai/dsh-session";
6
+ import { SessionPersistence, SessionPersistenceRevision, SessionStorageMetadata } from "@deepseek-ai/dsh-session-persistence";
7
+ //#region ../../vendor/deepseek-harness/vendor/cosmokit/lib/types/types.d.ts
8
+ declare function isArrayBufferLike(value: any): value is ArrayBufferLike;
9
+ declare function isArrayBufferSource(value: any): value is Binary.Source;
10
+ /** Binary source detection and base64/hex conversion helpers. */
11
+ declare namespace Binary {
12
+ type Source<T extends ArrayBufferLike = ArrayBufferLike> = T | ArrayBufferView<T>;
13
+ const is: typeof isArrayBufferLike;
14
+ const isSource: typeof isArrayBufferSource;
15
+ function fromSource<T extends ArrayBufferLike>(source: Source<T>): T;
16
+ function toBase64(source: Source): string;
17
+ function fromBase64(source: string): ArrayBuffer | Uint8Array<ArrayBuffer>;
18
+ function toHex(source: Source): string;
19
+ function fromHex(source: string): ArrayBuffer;
20
+ }
21
+ //#endregion
22
+ //#region ../../vendor/deepseek-harness/vendor/cosmokit/lib/types/misc.d.ts
23
+ /** String/symbol keyed dictionary type. */
24
+ type Dict<T = any, K extends string | symbol = string> = { [key in K]: T; };
25
+ //#endregion
26
+ //#region ../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts
27
+ /** The Standard Typed interface. This is a base type extended by other specs. */
28
+ interface StandardTypedV1<Input = unknown, Output = Input> {
29
+ /** The Standard properties. */
30
+ readonly "~standard": StandardTypedV1.Props<Input, Output>;
31
+ }
32
+ declare namespace StandardTypedV1 {
33
+ /** The Standard Typed properties interface. */
34
+ interface Props<Input = unknown, Output = Input> {
35
+ /** The version number of the standard. */
36
+ readonly version: 1;
37
+ /** The vendor name of the schema library. */
38
+ readonly vendor: string;
39
+ /** Inferred types associated with the schema. */
40
+ readonly types?: Types<Input, Output> | undefined;
41
+ }
42
+ /** The Standard Typed types interface. */
43
+ interface Types<Input = unknown, Output = Input> {
44
+ /** The input type of the schema. */
45
+ readonly input: Input;
46
+ /** The output type of the schema. */
47
+ readonly output: Output;
48
+ }
49
+ /** Infers the input type of a Standard Typed. */
50
+ type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"];
51
+ /** Infers the output type of a Standard Typed. */
52
+ type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"];
53
+ }
54
+ /** The Standard Schema interface. */
55
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
56
+ /** The Standard Schema properties. */
57
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
58
+ }
59
+ declare namespace StandardSchemaV1 {
60
+ /** The Standard Schema properties interface. */
61
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
62
+ /** Validates unknown input values. */
63
+ readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
64
+ }
65
+ /** The result interface of the validate function. */
66
+ type Result<Output> = SuccessResult<Output> | FailureResult;
67
+ /** The result interface if validation succeeds. */
68
+ interface SuccessResult<Output> {
69
+ /** The typed output value. */
70
+ readonly value: Output;
71
+ /** A falsy value for `issues` indicates success. */
72
+ readonly issues?: undefined;
73
+ }
74
+ interface Options {
75
+ /** Explicit support for additional vendor-specific parameters, if needed. */
76
+ readonly libraryOptions?: Record<string, unknown> | undefined;
77
+ }
78
+ /** The result interface if validation fails. */
79
+ interface FailureResult {
80
+ /** The issues of failed validation. */
81
+ readonly issues: ReadonlyArray<Issue>;
82
+ }
83
+ /** The issue interface of the failure output. */
84
+ interface Issue {
85
+ /** The error message of the issue. */
86
+ readonly message: string;
87
+ /** The path of the issue, if any. */
88
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
89
+ }
90
+ /** The path segment interface of the issue. */
91
+ interface PathSegment {
92
+ /** The key representing a path segment. */
93
+ readonly key: PropertyKey;
94
+ }
95
+ /** The Standard types interface. */
96
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
97
+ /** Infers the input type of a Standard. */
98
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
99
+ /** Infers the output type of a Standard. */
100
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
101
+ }
102
+ //#endregion
103
+ //#region ../../vendor/deepseek-harness/vendor/schemastery/lib/types/index.d.ts
104
+ declare const kSchema: unique symbol;
105
+ declare global {
106
+ namespace Schemastery {
107
+ /** Convert primitive constructors, constants, and existing schemas into a schema type. */
108
+ type From<X> = X extends string | number | boolean ? Schema<X> : X extends Schema ? X : X extends typeof String ? Schema<string> : X extends typeof Number ? Schema<number> : X extends typeof Boolean ? Schema<boolean> : X extends typeof Function ? Schema<Function, (...args: any[]) => any> : X extends Constructor<infer S> ? Schema<S> : never;
109
+ type TypeS1<X> = X extends Schema<infer S, unknown> ? S : never;
110
+ type Inverse<X> = X extends Schema<any, infer Y> ? (arg: Y) => void : never;
111
+ /** Input type accepted by a schema-like value. */
112
+ type TypeS<X> = TypeS1<From<X>>;
113
+ /** Output type returned by a schema-like value after validation. */
114
+ type TypeT<X> = ReturnType<From<X>>;
115
+ /** Resolver callback used by custom schema types registered with `Schema.extend()`. */
116
+ type Resolve = (data: any, schema: Schema, options: Options, strict?: boolean) => [any, any?];
117
+ /** Input type accepted by one schema in an intersection. */
118
+ type IntersectS<X> = From<X> extends Schema<infer S, unknown> ? S : never;
119
+ /** Output type returned by one schema in an intersection. */
120
+ type IntersectT<X> = Inverse<From<X>> extends ((arg: infer T) => void) ? T : never;
121
+ type TupleS<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeS<L>?, ...TupleS<R>] : any[];
122
+ type TupleT<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeT<L>?, ...TupleT<R>] : any[];
123
+ type ObjectS<X extends Dict> = { [K in keyof X]?: TypeS<X[K]> | null; } & Dict;
124
+ type ObjectT<X extends Dict> = { [K in keyof X]: TypeT<X[K]>; } & Dict;
125
+ type Constructor<T = any> = new (...args: any[]) => T;
126
+ /** Static constructor and factory methods exposed by the default `Schema` export. */
127
+ interface Static {
128
+ <T = any>(options: Partial<Schema<T>>): Schema<T>;
129
+ new <T = any>(options: Partial<Schema<T>>): Schema<T>;
130
+ prototype: Schema;
131
+ /** Validate a value against a schema node and return `[output, adaptedInput?]`. */
132
+ resolve: Resolve;
133
+ /** Infer a schema from a primitive value, constructor, or existing schema. */
134
+ from<X = any>(source?: X): From<X>;
135
+ /** Register a resolver for a custom schema `type`. */
136
+ extend(type: string, resolve: Resolve): void;
137
+ /** Accept any value without validation. */
138
+ any<T = any>(): Schema<T>;
139
+ /** Accept only nullable input. */
140
+ never(): Schema<never>;
141
+ /** Accept exactly one constant value. */
142
+ const<const T>(value: T): Schema<T>;
143
+ /** Accept strings, with optional metadata constraints added by instance methods. */
144
+ string(): Schema<string>;
145
+ /** Accept numbers, with optional range and step constraints. */
146
+ number(): Schema<number>;
147
+ /** Accept non-negative integer numbers. */
148
+ natural(): Schema<number>;
149
+ /** Accept a number between 0 and 1 and mark it as a slider. */
150
+ percent(): Schema<number>;
151
+ /** Accept booleans. */
152
+ boolean(): Schema<boolean>;
153
+ /** Accept `Date` instances or parse datetime strings into `Date` objects. */
154
+ date(): Schema<string | Date, Date>;
155
+ /** Accept `RegExp` instances or parse strings into regular expressions. */
156
+ regExp(flag?: string): Schema<string | RegExp, RegExp>;
157
+ /** Accept binary sources and normalize them to `ArrayBufferLike`. */
158
+ arrayBuffer(): Schema<Binary.Source, ArrayBufferLike>;
159
+ arrayBuffer(encoding: 'hex' | 'base64'): Schema<Binary.Source | string, ArrayBufferLike>;
160
+ /** Accept a numeric bitset or string keys and normalize to a number. */
161
+ bitset<K extends string>(bits: Partial<Record<K, number>>): Schema<number | readonly K[], number>;
162
+ /** Accept functions. */
163
+ function(): Schema<Function, (...args: any[]) => any>;
164
+ /** Accept instances of a constructor or objects whose constructor name matches. */
165
+ is(constructor: string): Schema;
166
+ is<T>(constructor: Constructor<T>): Schema<T>;
167
+ /** Accept arrays whose elements match `inner`. */
168
+ array<X>(inner: X): Schema<TypeS<X>[], TypeT<X>[]>;
169
+ /** Accept plain objects with values matching `inner` and optional key schema. */
170
+ dict<X, Y extends Schema<any, string> = Schema<string>>(inner: X, sKey?: Y): Schema<Dict<TypeS<X>, TypeS<Y>>, Dict<TypeT<X>, TypeT<Y>>>;
171
+ /** Accept tuple arrays where each index matches the corresponding schema. */
172
+ tuple<const X extends readonly any[]>(list: X): Schema<TupleS<X>, TupleT<X>>;
173
+ /** Accept plain objects whose declared properties match the schema dictionary. */
174
+ object<X extends Dict>(dict: X): Schema<ObjectS<X>, ObjectT<X>>;
175
+ /** Accept values matching at least one schema in `list`. */
176
+ union<const X>(list: readonly X[]): Schema<TypeS<X>, TypeT<X>>;
177
+ /** Accept values matching every schema in `list`, merging object outputs. */
178
+ intersect<const X>(list: readonly X[]): Schema<IntersectS<X>, IntersectT<X>>;
179
+ /** Validate with `inner`, then convert the result with `callback`. */
180
+ transform<X, T>(inner: X, callback: (value: TypeS<X>, options: Schemastery.Options) => T, preserve?: boolean): Schema<TypeS<X>, T>;
181
+ /** Defer construction of a recursive schema until validation or serialization. */
182
+ lazy<X extends Schema>(callback: () => X): X;
183
+ ValidationError: typeof ValidationError;
184
+ }
185
+ /** Runtime validation options shared by all schema calls. */
186
+ interface Options {
187
+ /** Remove invalid object properties instead of throwing when possible. */
188
+ autofix?: boolean;
189
+ /** Skip validation for selected values and schema nodes. */
190
+ ignore?(data: any, schema: Schema): boolean;
191
+ /** Path used to format nested validation errors. */
192
+ path?: (keyof any)[];
193
+ }
194
+ /** UI and validation metadata attached by schema builder methods. */
195
+ interface Meta<T = any> {
196
+ default?: T extends {} ? Partial<T> : T;
197
+ required?: boolean;
198
+ disabled?: boolean;
199
+ collapse?: boolean;
200
+ badges?: {
201
+ text: string;
202
+ type: string;
203
+ }[];
204
+ hidden?: boolean;
205
+ loose?: boolean;
206
+ role?: string;
207
+ extra?: any;
208
+ link?: string;
209
+ description?: string | Dict<string>;
210
+ comment?: string;
211
+ pattern?: {
212
+ source: string;
213
+ flags?: string;
214
+ };
215
+ max?: number;
216
+ min?: number;
217
+ step?: number;
218
+ }
219
+ }
220
+ /** Callable schema instance that validates input and returns normalized output. */
221
+ interface Schemastery<S = any, T = S> {
222
+ (data?: S | null, options?: Schemastery.Options): T;
223
+ new (data?: S | null, options?: Schemastery.Options): T;
224
+ [kSchema]: true;
225
+ uid: number;
226
+ meta: Schemastery.Meta<T>;
227
+ type: string;
228
+ sKey?: Schema;
229
+ inner?: Schema;
230
+ list?: Schema[];
231
+ dict?: Dict<Schema>;
232
+ bits?: Dict<number>;
233
+ callback?: Function;
234
+ constructor?: string | Function;
235
+ builder?: Function;
236
+ value?: T;
237
+ refs?: Dict<Schema>;
238
+ preserve?: boolean;
239
+ '~standard': StandardSchemaV1.Props;
240
+ /** Format this schema as a compact TypeScript-like type string. */
241
+ toString(inline?: boolean): string;
242
+ /** Serialize this schema, preserving shared and recursive references. */
243
+ toJSON(): Schema<S, T>;
244
+ /** Mark nullable input as invalid unless a default supplies a fallback. */
245
+ required(value?: boolean): Schema<S, T>;
246
+ /** Hide this schema node from UI renderers. */
247
+ hidden(value?: boolean): Schema<S, T>;
248
+ /** Return the default value instead of throwing when validation fails. */
249
+ loose(value?: boolean): Schema<S, T>;
250
+ /** Attach a renderer role and optional role-specific metadata. */
251
+ role(text: string, extra?: any): Schema<S, T>;
252
+ /** Attach an external documentation link. */
253
+ link(link: string): Schema<S, T>;
254
+ /** Set the fallback value used for nullable input. */
255
+ default(value: T): Schema<S, T>;
256
+ /** Attach an auxiliary comment for documentation or form UIs. */
257
+ comment(text: string): Schema<S, T>;
258
+ /** Attach a localized or plain description for documentation or form UIs. */
259
+ description(text: string): Schema<S, T>;
260
+ /** Mark this schema node as disabled for form UIs. */
261
+ disabled(value?: boolean): Schema<S, T>;
262
+ /** Request collapsed rendering for nested form UIs. */
263
+ collapse(value?: boolean): Schema<S, T>;
264
+ /** Add a deprecated badge to this schema node. */
265
+ deprecated(): Schema<S, T>;
266
+ /** Add an experimental badge to this schema node. */
267
+ experimental(): Schema<S, T>;
268
+ /** Require strings to match a regular expression. */
269
+ pattern(regexp: RegExp): Schema<S, T>;
270
+ /** Set an inclusive maximum for numbers or collection lengths. */
271
+ max(value: number): Schema<S, T>;
272
+ /** Set an inclusive minimum for numbers or collection lengths. */
273
+ min(value: number): Schema<S, T>;
274
+ /** Set the numeric increment constraint. */
275
+ step(value: number): Schema<S, T>;
276
+ /** Add or replace an object property schema. */
277
+ set(key: string, value: Schema): Schema<S, T>;
278
+ /** Append a tuple, union, or intersection member schema. */
279
+ push(value: Schema): Schema<S, T>;
280
+ /** Remove values equal to schema defaults from normalized output. */
281
+ simplify(value?: any): any;
282
+ /** Return a schema clone with descriptions merged from locale messages. */
283
+ i18n(messages: Dict): Schema<S, T>;
284
+ /** Attach arbitrary metadata consumed by form renderers and downstream tools. */
285
+ extra<K extends keyof Schemastery.Meta>(key: K, value: Schemastery.Meta[K]): Schema<S, T>;
286
+ }
287
+ }
288
+ declare class ValidationError extends TypeError {
289
+ options: Schemastery.Options;
290
+ name: string;
291
+ constructor(message: string, options: Schemastery.Options);
292
+ static is(error: any): error is ValidationError;
293
+ }
294
+ type Schema<S = any, T = S> = Schemastery<S, T>;
295
+ declare const Schema: Schemastery.Static;
296
+ //#endregion
297
+ //#region ../session-rdb/src/import.d.ts
298
+ declare function parseJsonlArtifact(content: string): SessionStorageMetadata & {
299
+ events: SessionEvent$1[];
300
+ };
301
+ //#endregion
302
+ //#region ../../vendor/deepseek-harness/packages/settings/settings/lib/types/redact.d.ts
303
+ /** One schema-declared secret position inside a redacted value. */
304
+ interface RedactedSecret {
305
+ /** Path from the section root to the removed field (concrete dict keys and array indexes included). */
306
+ path: string[];
307
+ /** Whether the field held a value before redaction. */
308
+ set: boolean;
309
+ }
310
+ //#endregion
311
+ //#region ../../vendor/deepseek-harness/packages/util/brand/lib/types/index.d.ts
312
+ /**
313
+ * Duplicate-install-safe nominal primitive helpers.
314
+ *
315
+ * A brand makes structurally identical strings or numbers non-interchangeable
316
+ * at the type level: a `SessionId` cannot be passed where a `ToolCallId` is
317
+ * expected, and an event sequence cannot be passed as a log offset. Comparison,
318
+ * logging, and serialization retain the underlying primitive behavior.
319
+ *
320
+ * This package owns no concrete domain value and keeps no runtime identity or mutable
321
+ * state, so independently installed copies produce interchangeable values.
322
+ *
323
+ * @module @deepseek-ai/dsh-brand
324
+ */
325
+ declare const BRAND: unique symbol;
326
+ /** A string carrying a compile-time-only brand `B`. */
327
+ type Branded<B extends string> = string & {
328
+ readonly [BRAND]: B;
329
+ };
330
+ //#endregion
331
+ //#region ../../vendor/deepseek-harness/packages/settings/settings/lib/types/types.d.ts
332
+ /** Nominal id of one registered settings namespace. */
333
+ type SettingsNamespace = Branded<'SettingsNamespace'>;
334
+ /** Origin of one committed settings change. */
335
+ type SettingsUpdateSource = 'update' | 'provider';
336
+ declare module '@deepseek-ai/cordis' {
337
+ interface Events {
338
+ /**
339
+ * Committed change to one registered namespace's resolved value. Emitted
340
+ * after the provider persisted (for `update`) or published (`provider`)
341
+ * the change; never emitted when the resolved value is deep-equal.
342
+ * Listener failures are contained and logged — a sync throw and an async
343
+ * rejection alike — except `INVARIANT`-coded failures, which rethrow
344
+ * after every listener ran; that rethrow reaches the emitter only from
345
+ * synchronous listeners, so invariant checks on this event must not be
346
+ * async functions.
347
+ * @param ns - the namespace whose resolved value changed.
348
+ * @param next - the new resolved value.
349
+ * @param prev - the previous resolved value.
350
+ * @param source - whether the change entered through `update()` or the provider.
351
+ * @mode emit
352
+ */
353
+ 'settings/updated'(ns: SettingsNamespace, next: unknown, prev: unknown, source: SettingsUpdateSource): void;
354
+ /**
355
+ * One registered namespace's RAW user section changed, whether or not the
356
+ * resolved value did. `settings/updated` is the consumer-facing event and
357
+ * stays deep-equal-gated; this one exists for configuration surfaces,
358
+ * which must learn that a field went from inherited to overridden (same
359
+ * resolved value, different meaning) and that their held revision is
360
+ * stale. Listener containment matches `settings/updated`.
361
+ * @param ns - the namespace whose stored section changed.
362
+ * @param revision - the namespace's new revision.
363
+ * @mode emit
364
+ */
365
+ 'settings/document-updated'(ns: SettingsNamespace, revision: number): void;
366
+ }
367
+ }
368
+ //#endregion
369
+ //#region ../../vendor/deepseek-harness/packages/settings/settings/lib/types/index.d.ts
370
+ type LowercaseLetter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
371
+ type DecimalDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
372
+ type NamespaceCharacter = LowercaseLetter | DecimalDigit | '-';
373
+ type ValidNamespaceTail<Value extends string> = Value extends '' ? true : Value extends `${NamespaceCharacter}${infer Rest}` ? ValidNamespaceTail<Rest> : false;
374
+ type SettingsNamespaceInput<Value extends string> = Value extends SettingsNamespace ? Value : string extends Value ? string : Value extends `${LowercaseLetter}${infer Rest}` ? ValidNamespaceTail<Rest> extends true ? Value : never : never;
375
+ /** When a namespace's changes take effect for its owner. */
376
+ type SettingsApplies = 'live' | 'restart';
377
+ /** Registration options beyond the namespace schema. */
378
+ interface SettingsRegisterOptions<T> {
379
+ /** Composition-layer values resolved below the user layer (entry-config subset). */
380
+ base?: Partial<T>;
381
+ /** Owner's effect timing, surfaced to configuration UIs; defaults to `live`. */
382
+ applies?: SettingsApplies;
383
+ /**
384
+ * Reject a resolved section the owner could not act on, for constraints its
385
+ * schema cannot express — a cross-field requirement, or one field's validity
386
+ * depending on another's. Throwing here refuses the *write* that produced the
387
+ * value, so a caller learns at `update`/`replace`/`mutate` instead of storing
388
+ * something that would silently disable the owner.
389
+ *
390
+ * Kept separate from the schema because the schema is also what a
391
+ * configuration surface renders and what an absent section resolves through;
392
+ * folding a cross-field check into it would change both.
393
+ *
394
+ * Once the owner is registered, a stored section that fails this keeps the
395
+ * namespace's last good value and warns, exactly as a schema failure does,
396
+ * so an externally edited document cannot strand a running owner. At
397
+ * registration there is no last good value yet, so a stored section that
398
+ * already fails rejects the registration itself — again exactly as a schema
399
+ * failure does.
400
+ * @param value - the resolved section, schema-valid by construction.
401
+ */
402
+ validate?: (value: T) => void;
403
+ }
404
+ /** One registered namespace as surfaced to configuration UIs. */
405
+ interface SettingsDescriptor {
406
+ /** The registered namespace. */
407
+ ns: SettingsNamespace;
408
+ /** Serialized schemastery schema (`schema.toJSON()`). */
409
+ schema: unknown;
410
+ /** Current resolved value. */
411
+ value: unknown;
412
+ /**
413
+ * Monotonic revision of the raw user section this descriptor was read at.
414
+ * Send it back as `expectedRevision` on a write to refuse a stale one.
415
+ */
416
+ revision: number;
417
+ /** Registrant's composition `base` layer (detached), when one was declared. */
418
+ base?: unknown;
419
+ /**
420
+ * Raw user section from the stored document (detached), when one exists and
421
+ * is well-formed; a field's presence here is what marks it user-overridden.
422
+ */
423
+ user?: unknown;
424
+ /** Owner's declared effect timing. */
425
+ applies: SettingsApplies;
426
+ /** Schema-declared secret positions; present only under `redactSecrets`. */
427
+ secrets?: RedactedSecret[];
428
+ }
429
+ /** Options for {@link SettingsProvider.describe}. */
430
+ interface SettingsDescribeOptions {
431
+ /**
432
+ * Strip `role('secret')` fields from `value`/`base`/`user` and enumerate
433
+ * them in each descriptor's `secrets`. Every wire surface MUST pass this;
434
+ * the verbatim default exists for same-process configuration UIs only.
435
+ */
436
+ redactSecrets?: boolean;
437
+ }
438
+ /** Owner-facing handle for one registered namespace. */
439
+ interface SettingsScope<T> {
440
+ /** Current resolved value: schema defaults, then `base`, then the user layer. */
441
+ get(): T;
442
+ /**
443
+ * Observe committed changes to this namespace's resolved value. Invocations
444
+ * of one callback run asynchronously, one at a time, in commit order; a
445
+ * rejection is contained and logged like a sync throw. After the disposer
446
+ * returns, no further invocation starts — one already queued is skipped;
447
+ * one already started still settles, and service disposal waits for it.
448
+ * @param callback - invoked after each commit with the next and previous values.
449
+ * @returns the disposer removing this observer.
450
+ */
451
+ watch(callback: (next: T, prev: T) => void | Promise<void>): () => void;
452
+ /**
453
+ * Merge a partial patch into this namespace's user layer and persist it.
454
+ * @param patch - plain-object patch over the user section; JSON-compatible data
455
+ * only (non-JSON values reject with their path before anything persists).
456
+ */
457
+ update(patch: object): Promise<void>;
458
+ /**
459
+ * Replace this namespace's user section wholesale; absent keys re-inherit
460
+ * the composition `base` and schema defaults (`replace({})` resets all).
461
+ * @param section - the complete next user section; JSON-compatible data only,
462
+ * as for {@link update}.
463
+ */
464
+ replace(section: object): Promise<void>;
465
+ }
466
+ declare module '@deepseek-ai/cordis' {
467
+ interface Context {
468
+ settings: SettingsProvider;
469
+ }
470
+ }
471
+ /**
472
+ * One path-addressed edit to a namespace's user section. Path mutation exists
473
+ * for a caller holding an INCOMPLETE view of the section — a configuration UI
474
+ * reads the redacted descriptor, which by construction never received the
475
+ * `role('secret')` fields. Such a caller can name the field it means without
476
+ * restating the section: a wholesale `replace` rebuilt from a redacted
477
+ * document silently deletes every secret the wire never returned.
478
+ */
479
+ type SettingsPathOp = {
480
+ op: 'set';
481
+ path: readonly string[];
482
+ value: unknown;
483
+ } | {
484
+ op: 'unset';
485
+ path: readonly string[];
486
+ };
487
+ /**
488
+ * Abstract settings service. Providers implement raw-document storage
489
+ * (`load`/`persist`) and push external changes through {@link Settings.publish};
490
+ * the base class owns namespace registration, resolution, validation, change
491
+ * detection, and the `settings/updated` commit event.
492
+ */
493
+ declare abstract class SettingsProvider extends Service {
494
+ private readonly registrations;
495
+ /** Latest published raw document; empty until the provider's first publish. */
496
+ private document;
497
+ /** Per-namespace write chains; settled tails, so a failure never poisons the queue. */
498
+ private readonly writeQueues;
499
+ /** In-flight watcher invocation segments, drained by the dispose teardown. */
500
+ private readonly pendingTails;
501
+ /** Set at service dispose: refuse new writes while queued ones drain. */
502
+ private stopped;
503
+ /** Opaque read of {@link stopped}: control flow cannot narrow it across awaits. */
504
+ private isStopped;
505
+ constructor(ctx: Context);
506
+ /**
507
+ * Load the provider's document once and publish it before the service
508
+ * becomes injectable, and register the write-drain teardown. Providers with
509
+ * their own init (watchers, connections) delegate here first via
510
+ * `yield* super[Service.init]()`; their disposers then run before the drain.
511
+ */
512
+ [Service.init](): AsyncGenerator<() => Promise<void> | void, void, void>;
513
+ /** Whether {@link update} may persist through this provider. */
514
+ abstract readonly writable: boolean;
515
+ /**
516
+ * Absolute path of the provider's user-editable document, when its storage
517
+ * is one local file. Configuration surfaces use this only as availability
518
+ * metadata; the guarded open operation resolves the path again Host-side.
519
+ * Non-file providers leave it undefined and expose no open-document affordance.
520
+ * @returns the absolute local document path, or undefined for non-file storage.
521
+ */
522
+ get documentPath(): string | undefined;
523
+ /**
524
+ * Prepare the provider's user-editable document for a native editor. File
525
+ * providers may materialize an absent document before returning its path;
526
+ * non-file providers return undefined.
527
+ * @returns the absolute local document path, or undefined for non-file storage.
528
+ */
529
+ prepareDocument(): Promise<string | undefined>;
530
+ /**
531
+ * Read the provider's current raw document (namespace to raw section).
532
+ * @returns the detached raw document.
533
+ */
534
+ protected abstract load(): Promise<Record<string, unknown>>;
535
+ /**
536
+ * Durably store one namespace's merged user section.
537
+ * @param ns - the namespace being written.
538
+ * @param section - the complete merged user section to store.
539
+ */
540
+ protected abstract persist(ns: SettingsNamespace, section: Record<string, unknown>): Promise<void>;
541
+ /**
542
+ * Register a namespace schema and receive its owner scope. The registration
543
+ * is an effect on the calling plugin's fiber: disposing that fiber removes
544
+ * the namespace and its observers. An invalid stored section fails the
545
+ * registration itself — the earliest point where the schema can judge it.
546
+ * @param ns - unique namespace; duplicate registration fails loud.
547
+ * @param schema - schemastery schema resolving this namespace's value.
548
+ * @param options - composition `base` layer and effect timing.
549
+ * @returns the owner scope for reads, observation, and updates.
550
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
551
+ */
552
+ register<const Namespace extends string, T>(ns: Namespace & SettingsNamespaceInput<Namespace>, schema: Schema<T>, options?: SettingsRegisterOptions<T>): SettingsScope<T>;
553
+ /**
554
+ * Attach one optional-settings consumer to this provider. The consumer
555
+ * registers its composition entry as the base layer while this provider is
556
+ * present, then falls back to that entry if the provider detaches.
557
+ * @param owner - consumer context whose unload suppresses fallback work.
558
+ * @param ns - consumer-owned settings namespace.
559
+ * @param schema - schema resolving the namespace.
560
+ * @param entry - composition entry used as the base and fallback value.
561
+ * @param hooks - source sink, change notification, and optional validation.
562
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
563
+ */
564
+ installSection<const Namespace extends string, T>(owner: Context, ns: Namespace & SettingsNamespaceInput<Namespace>, schema: Schema<T>, entry: T, hooks: SettingsSectionHooks<T>): void;
565
+ /**
566
+ * Describe every registered namespace for configuration surfaces, including
567
+ * the composition `base` and raw user layers so a form can mark which fields
568
+ * the user overrode (presence in `user`) and what a reset returns to.
569
+ * @param options - redaction switch; wire surfaces must redact.
570
+ * @returns one descriptor per registered namespace, in registration order.
571
+ */
572
+ describe(options?: SettingsDescribeOptions): SettingsDescriptor[];
573
+ /**
574
+ * Read one registered namespace's resolved value.
575
+ * @param ns - the namespace to read.
576
+ * @returns the resolved value, or `undefined` while unregistered.
577
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
578
+ */
579
+ get<const Namespace extends string>(ns: Namespace & SettingsNamespaceInput<Namespace>): unknown;
580
+ /**
581
+ * Merge a patch into one registered namespace's user layer, validate the
582
+ * resolved candidate, persist through the provider, then commit and emit.
583
+ * A validation failure rejects before anything is persisted. Writes to one
584
+ * namespace are serialized: concurrent updates apply in call order, each
585
+ * merging over the previous write's committed section.
586
+ * @param ns - the registered namespace to update.
587
+ * @param patch - plain-object patch over the user section.
588
+ * @param expectedRevision - the descriptor `revision` the caller read; a
589
+ * namespace that moved past it rejects with {@link SettingsConflictError}.
590
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
591
+ */
592
+ update<const Namespace extends string>(ns: Namespace & SettingsNamespaceInput<Namespace>, patch: object, expectedRevision?: number): Promise<void>;
593
+ /**
594
+ * Replace one registered namespace's user section wholesale, validate,
595
+ * persist, then commit and emit. Keys absent from `section` fall back to the
596
+ * composition `base` and schema defaults — this is the removal/reset path a
597
+ * merge-only patch cannot express (`replace({})` re-inherits everything).
598
+ * @param ns - the registered namespace to replace.
599
+ * @param section - the complete next user section.
600
+ * @param expectedRevision - the descriptor `revision` the caller read; a
601
+ * namespace that moved past it rejects with {@link SettingsConflictError}.
602
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
603
+ */
604
+ replace<const Namespace extends string>(ns: Namespace & SettingsNamespaceInput<Namespace>, section: object, expectedRevision?: number): Promise<void>;
605
+ /**
606
+ * Apply path-addressed edits to one registered namespace's user section,
607
+ * validate, persist, then commit and emit. The ops are applied to the
608
+ * section as it stands when the write reaches the front of the queue, so a
609
+ * caller never has to restate fields it did not touch — and, crucially,
610
+ * cannot delete fields it never saw. This is the write path for any caller
611
+ * holding a redacted view; `replace` remains the wholesale reset.
612
+ * @param ns - the registered namespace to edit.
613
+ * @param ops - ordered path edits; later ops observe earlier ones.
614
+ * @param expectedRevision - the descriptor `revision` the caller read; a
615
+ * namespace that moved past it rejects with {@link SettingsConflictError}.
616
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
617
+ */
618
+ mutate<const Namespace extends string>(ns: Namespace & SettingsNamespaceInput<Namespace>, ops: readonly SettingsPathOp[], expectedRevision?: number): Promise<void>;
619
+ /** Validate a write, then queue it on the namespace's serialized write chain. */
620
+ private write;
621
+ /**
622
+ * Provider hook: commit a complete raw document observed in storage. Each
623
+ * registered namespace re-resolves; an invalid section keeps that
624
+ * namespace's last good value and warns, other namespaces still commit.
625
+ * @param doc - the detached raw document (unregistered sections preserved).
626
+ * @param source - change origin; defaults to `provider`.
627
+ */
628
+ protected publish(doc: Record<string, unknown>, source?: SettingsUpdateSource): void;
629
+ /** Read one namespace's raw user section, rejecting non-object sections. */
630
+ private section;
631
+ /** Resolve one namespace value: schema defaults, then `base`, then the user layer. */
632
+ private resolve;
633
+ /**
634
+ * Advance a namespace's revision when its RAW section changed, and announce
635
+ * it. Deliberately independent of {@link commit}'s resolved-value equality:
636
+ * storing an override equal to the composition base leaves the resolved
637
+ * value alone but changes what the document says, which is exactly what a
638
+ * configuration surface must re-read.
639
+ */
640
+ private bumpRevision;
641
+ /** Contained fan-out of `settings/document-updated`, mirroring {@link commit}'s. */
642
+ private emitDocumentUpdated;
643
+ /** Commit a resolved value when changed: swap, notify watchers, emit the event. */
644
+ private commit;
645
+ /** Contained-watcher diagnostic shared by the sync and async failure paths. */
646
+ private warnWatcherFailure;
647
+ /** Contained-listener diagnostic shared by the sync and async failure paths. */
648
+ private warnListenerFailure;
649
+ }
650
+ /** Hooks a consumer hands to {@link SettingsProvider.installSection}. */
651
+ interface SettingsSectionHooks<T> {
652
+ /**
653
+ * Receive the active configuration source: the resolved settings scope
654
+ * while one is attached, the composition entry otherwise. Called before
655
+ * the matching `onChange` at attach and at detach.
656
+ * @param current - thunk returning the currently authoritative value.
657
+ */
658
+ setSource(current: () => T): void;
659
+ /**
660
+ * Re-judge anything derived from the source — registration-level facts,
661
+ * memoized resolutions — after an attach, a detach, or a committed change.
662
+ */
663
+ onChange(): void;
664
+ /**
665
+ * Reject a resolved section this consumer could not act on, for constraints
666
+ * its schema cannot express. See {@link SettingsRegisterOptions.validate}.
667
+ * @param value - the resolved section, schema-valid by construction.
668
+ */
669
+ validate?: (value: T) => void;
670
+ }
671
+ //#endregion
672
+ //#region ../session-rdb/src/testing/helpers.d.ts
673
+ declare class EmptySettings extends SettingsProvider {
674
+ constructor(ctx: Context);
675
+ get writable(): boolean;
676
+ protected load(): Promise<Record<string, unknown>>;
677
+ protected persist(_ns: SettingsNamespace, _section: Record<string, unknown>): Promise<void>;
678
+ }
679
+ //#endregion
680
+ //#region ../session-rdb/src/testing/contract.d.ts
681
+ declare function meta(id: string, cwd?: string): SessionHeader$1;
682
+ declare function oneTurnLog(): SessionEvent$1[];
683
+ //#endregion
684
+ //#region src/testing.d.ts
685
+ interface Harness {
686
+ ctx: Context;
687
+ editor: SessionEditor;
688
+ dispose: () => Promise<void>;
689
+ }
690
+ declare function harness(): Promise<Harness>;
691
+ declare function twoTurnLog(): SessionEvent[];
692
+ declare function createPersisted(ctx: Context, id: string, events: readonly SessionEvent[], header?: SessionHeader): Promise<void>;
693
+ /** 构造一条 user/message 事件。 */
694
+ declare function userMessage(seq: number, id: string, text: string, time?: number): SessionEvent;
695
+ /** 构造一条 assistant/message 事件(纯文本回复)。 */
696
+ declare function assistantMessage(seq: number, turn: number, step: number, id: string, text: string, time?: number): SessionEvent;
697
+ /** 真实 agent-loop 形状的一轮:轮首输入 + 可选 followup,可闭合。 */
698
+ declare function turnLog(base: number, turn: number, opts?: {
699
+ users?: Array<{
700
+ id: string;
701
+ text: string;
702
+ }>;
703
+ closed?: boolean;
704
+ time?: number;
705
+ }): SessionEvent[];
706
+ //#endregion
707
+ export { type BranchTimeline, EmptySettings, Harness, Session, type SessionEvent, type SessionHeader, SessionIdBrand, SessionSeq, SessionStore, TokenMeter, assistantMessage, createPersisted, harness, meta, oneTurnLog, parseJsonlArtifact, turnLog, twoTurnLog, userMessage };