/**
 * settings domain contract: the web face of the user-settings seam
 * (`ctx.settings`). Every payload that leaves this domain is redacted by the
 * seam (`describe({ redactSecrets: true })` semantics): `role('secret')`
 * fields never ride a response in any layer, and the `secrets` slot list is
 * how a form learns a write-only field exists and whether it is configured.
 */
import type { RpcRequest, RpcResponse } from './rpc.ts';
/** One schema-declared secret slot inside a redacted namespace value. */
export interface SettingsSecretView {
    /** Path from the section root to the removed field. */
    path: string[];
    /** Whether the slot currently holds a value (the value itself never rides). */
    set: boolean;
}
/** Wire view of one registered settings namespace. */
export interface SettingsNamespaceView {
    /** Namespace key (`llm-deepseek`, `llm-pi-ai`, …). */
    ns: string;
    /** Serialized schemastery schema envelope (`schema.toJSON()`); rehydrate with `new Schema(json)`. */
    schema: unknown;
    /** Redacted resolved value (schema defaults → composition base → user layer). */
    value: unknown;
    /** Redacted composition base layer, when the registrant declared one. */
    base?: unknown;
    /** Redacted raw user section, when one exists; a field's presence here marks it user-overridden. */
    user?: unknown;
    /** When the owner applies changes. */
    applies: 'live' | 'restart';
    /** Every schema-declared secret slot with its configured state. */
    secrets: SettingsSecretView[];
    /**
     * Monotonic revision of the raw user section this view was read at. Send it
     * back as `expectedRevision` on a write so a stale editor is refused rather
     * than silently overwriting a concurrent change.
     */
    revision: number;
}
/**
 * One path-addressed edit carried by `settings.mutate`. `set` writes the
 * value at the path (creating intermediate objects); `unset` removes it. The
 * empty path addresses the section root.
 */
export type SettingsPathOpView = {
    op: 'set';
    path: string[];
    value: unknown;
} | {
    op: 'unset';
    path: string[];
};
/** Settings-domain unary methods (the map keys settings.* of RpcMethodMap). */
export interface SettingsApi {
    /**
     * Describe every registered namespace: redacted layered values plus the
     * serialized schema a client renders its form from. `hasDocument` reports
     * whether a file-backed provider owns a local document without exposing its
     * Host path. This method is loopback-only; `writable: false` (read-only
     * provider) tells the client to disable every write control.
     */
    describe(request: RpcRequest<{}>): Promise<RpcResponse<{
        writable: boolean;
        hasDocument: boolean;
        namespaces: SettingsNamespaceView[];
    }>>;
    /**
     * Materialize the configured local document when absent and ask the Host to
     * hand it to the platform text-document opener. macOS forces a text editor;
     * Linux and Windows use the desktop file association. The request carries
     * no path, so the browser cannot choose an arbitrary Host filesystem target.
     */
    openDocument(request: RpcRequest<{}>, signal: AbortSignal): Promise<RpcResponse<{
        opened: true;
    }>>;
    /**
     * Merge a patch into one namespace's user layer (validate → persist →
     * commit). Secret-role fields may be INCLUDED in the patch (write-only
     * direction); a form that leaves a secret untouched simply omits it and the
     * merge preserves the stored value. Responds with the namespace's new
     * redacted view; a schema or storage rejection is `settings-rejected`.
     */
    update(request: RpcRequest<{
        ns: string;
        patch: object;
        expectedRevision?: number;
    }>): Promise<RpcResponse<SettingsNamespaceView>>;
    /**
     * Replace one namespace's user section wholesale — the removal/reset path a
     * merge cannot express (`section: {}` resets to composition defaults). Keys
     * absent from `section` are dropped, secrets included: a client must first
     * fold the descriptor's `user` layer (and re-supply any secret it wants to
     * keep) or accept the reset.
     */
    replace(request: RpcRequest<{
        ns: string;
        section: object;
        expectedRevision?: number;
    }>): Promise<RpcResponse<SettingsNamespaceView>>;
    /**
     * Apply path-addressed edits to one namespace's user section, resolved
     * against the section as stored — NOT against whatever the caller last
     * read. This is the removal path for any client holding the redacted
     * descriptor: it names the field it means, so a secret the wire never
     * returned cannot be deleted as a side effect. `replace` remains the
     * deliberate wholesale reset.
     */
    mutate(request: RpcRequest<{
        ns: string;
        ops: SettingsPathOpView[];
        expectedRevision?: number;
    }>): Promise<RpcResponse<SettingsNamespaceView>>;
}
//# sourceMappingURL=settings.d.ts.map