@prettier-ai/dsh-client-ui-settings-models 0.1.2-alpha.1

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.
@@ -0,0 +1,108 @@
1
+ /** Copy dictionaries for the Models settings section. */
2
+ /** English strings (the key-set source of truth for this pair). */
3
+ export declare const en: {
4
+ nav: string;
5
+ title: string;
6
+ intro: string;
7
+ edit: string;
8
+ editProvider: string;
9
+ remove: string;
10
+ removeProvider: string;
11
+ deleteTitle: string;
12
+ deleteDescription: string;
13
+ deleteDescriptionWithCredential: string;
14
+ deleteConfirm: string;
15
+ deleting: string;
16
+ add: string;
17
+ provider: string;
18
+ close: string;
19
+ cancel: string;
20
+ apply: string;
21
+ applying: string;
22
+ savedProvider: string;
23
+ credentialConfigured: string;
24
+ credentialMissing: string;
25
+ readOnly: string;
26
+ loadFailed: string;
27
+ conflict: string;
28
+ retry: string;
29
+ keyInput: string;
30
+ keyPlaceholder: string;
31
+ keyPlaceholderNative: string;
32
+ keyStored: string;
33
+ keyEnvLocked: string;
34
+ customized: string;
35
+ baseUrl: string;
36
+ baseUrlDefault: string;
37
+ models: string;
38
+ modelsInherited: string;
39
+ modelsCustomized: string;
40
+ resetModels: string;
41
+ model: string;
42
+ modelId: string;
43
+ modelName: string;
44
+ modelNamePlaceholder: string;
45
+ contextWindow: string;
46
+ contextWindowPlaceholder: string;
47
+ maxTokens: string;
48
+ maxTokensPlaceholder: string;
49
+ modelAdvanced: string;
50
+ addModel: string;
51
+ removeModel: string;
52
+ modelsEmpty: string;
53
+ keyBlank: string;
54
+ keyBlankNew: string;
55
+ keyIllegalCharacters: string;
56
+ modelIdRequired: string;
57
+ modelIdDuplicate: string;
58
+ modelNameInvalid: string;
59
+ modelContextInvalid: string;
60
+ modelMaxTokensInvalid: string;
61
+ advancedHint: string;
62
+ modelCapacityInvalid: string;
63
+ modelDuplicate: string;
64
+ modelContextWindow: string;
65
+ modelMaxTokens: string;
66
+ fetchModels: string;
67
+ fetching: string;
68
+ fetchNeedsBaseUrl: string;
69
+ fetchEmpty: string;
70
+ fetchTitle: string;
71
+ fetchDescription: string;
72
+ fetchSelectAll: string;
73
+ fetchDeselectAll: string;
74
+ fetchAdopt: string;
75
+ customAdd: string;
76
+ customTitle: string;
77
+ customTag: string;
78
+ customRoute: string;
79
+ customRouteHint: string;
80
+ customRouteInvalid: string;
81
+ customRouteTaken: string;
82
+ customDisplayName: string;
83
+ customApi: string;
84
+ customApiUnset: string;
85
+ customNeedsBaseUrl: string;
86
+ customNeedsModels: string;
87
+ customBaseUrlPlaceholder: string;
88
+ settingsPathUnresolvable: string;
89
+ create: string;
90
+ creating: string;
91
+ welcomeTitle: string;
92
+ welcomeBody: string;
93
+ welcomeContinue: string;
94
+ welcomeError: string;
95
+ onboardingTitle: string;
96
+ onboardingDescription: string;
97
+ onboardingLater: string;
98
+ onboardingSave: string;
99
+ onboardingSaving: string;
100
+ keyRequired: string;
101
+ };
102
+ /** The settings.models namespace key union. */
103
+ export type ModelsKey = keyof typeof en;
104
+ /** Chinese strings (same keys as {@link en}). */
105
+ export declare const zh: {
106
+ [Key in keyof typeof en]: string;
107
+ };
108
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { SettingsSchemaService } from '@prettier-ai/dsh-client-ui-settings/client';
2
+ /** Plain schema callbacks exposed to Models stores and presentation components. */
3
+ export type SettingsSchemaOperations = Pick<SettingsSchemaService, 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'>;
4
+ /**
5
+ * Hide the Cordis service identity behind bound schema callbacks.
6
+ * @param service - settings-owned schema service available in the apply context.
7
+ * @returns callbacks that cannot expose the service context to React components.
8
+ */
9
+ export declare function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations;
10
+ //# sourceMappingURL=schema-operations.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Models-page extension slots — the two seats through which a plugin
3
+ * distributed outside this repository adds UI to the Models settings section
4
+ * without editing it.
5
+ *
6
+ * `settings.models.provider-card` is keyed by the row's owning settings
7
+ * namespace (`ProviderDirectoryEntry.settingsNs`): an adapter family's
8
+ * companion plugin registers one entry under the family's namespace and
9
+ * receives every card of that family — shipped, added, and hand-declared rows
10
+ * alike — while the section never learns what the namespace means. Keying on
11
+ * the namespace follows `settings.plugin.item`, and the key domain stays the
12
+ * open string space because hand-declared route ids are user-chosen at
13
+ * runtime.
14
+ *
15
+ * TYPE HOME RATIONALE: the Models section declares these slots at runtime,
16
+ * and a plugin registering an extension already depends on this package for
17
+ * the declaration. The types therefore live with their declarer.
18
+ */
19
+ import type { ProviderDirectoryEntry } from './store.ts';
20
+ declare module '@prettier-ai/dsh-client-ui-slots' {
21
+ interface SlotMap {
22
+ /**
23
+ * One provider card's adapter extension area, dispatched with
24
+ * `entryKey = settingsNs` on every card that renders a directory row: a
25
+ * saved row's card (its first-run setup posture included) and the
26
+ * add-provider draft card. The hand-declared draft card has no directory
27
+ * row yet, so it dispatches nothing until saved. Without a registrant the
28
+ * area renders nothing.
29
+ */
30
+ 'settings.models.provider-card': {
31
+ kind: 'keyed';
32
+ scope: 'root';
33
+ owner: ProviderCardExtrasOwnerProps;
34
+ };
35
+ /**
36
+ * Ordered extension area after the provider rows and the add controls.
37
+ * Without a registrant the area renders nothing.
38
+ */
39
+ 'settings.models.footer': {
40
+ kind: 'list';
41
+ scope: 'root';
42
+ owner: ModelsFooterOwnerProps;
43
+ };
44
+ }
45
+ }
46
+ /** Owner share of one provider-card extension occurrence. */
47
+ export interface ProviderCardExtrasOwnerProps {
48
+ /** The card's directory row (route id, display name, settings address, live state). */
49
+ provider: ProviderDirectoryEntry;
50
+ /** Whether any layer configures this provider (its profile resolves); `false` while the add-provider draft edits a dormant row. */
51
+ configured: boolean;
52
+ /** Whether the row's referenced api-key credential is confirmed configured (the page's credential join). */
53
+ keyConfigured: boolean;
54
+ }
55
+ /** Owner share of the footer area (the section supplies nothing). */
56
+ export interface ModelsFooterOwnerProps {
57
+ /** Marker field: footer owner props are intentionally empty. */
58
+ children?: never;
59
+ }
60
+ //# sourceMappingURL=slot-contract.d.ts.map
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Models settings page store: one snapshot joining the configurable-provider
3
+ * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
4
+ * the settings namespaces (shared settings mirror),
5
+ * and the referenced credentials (`credentials/describe`). The host stays the
6
+ * single fact source — every mutation writes through the wire and the page
7
+ * re-renders from the next describe, pushed or refetched.
8
+ */
9
+ import type { ClientRemote, CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView } from '@prettier-ai/dsh-api-remotes/client';
10
+ import type { SnapshotStore } from '@prettier-ai/dsh-client-store';
11
+ import type { SettingsDescribeFace, SettingsRemote } from '@prettier-ai/dsh-client-ui-settings/client';
12
+ import type { SettingsSchemaOperations } from './schema-operations.ts';
13
+ /** The credentials Remote methods the Models page reads and writes through. */
14
+ export type ModelsCredentials = Pick<ClientRemote['credentials'], 'describe' | 'set' | 'unset'>;
15
+ /** LLM Remote methods used by the Models page. */
16
+ export type ModelsLlm = Pick<ClientRemote['llm'], 'discoverModels' | 'listConfigurableProviders' | 'listProviders'>;
17
+ /** One provider row after joining the configurable directory with live routes. */
18
+ export interface ProviderDirectoryEntry {
19
+ readonly provider: string;
20
+ readonly displayName: string;
21
+ readonly settingsNs: string;
22
+ readonly settingsPath: readonly string[];
23
+ readonly active: boolean;
24
+ readonly declared?: boolean;
25
+ }
26
+ /**
27
+ * Join declared configurable providers with the currently registered routes.
28
+ * @param registered - live provider routes in registration order.
29
+ * @param directory - declared configurable providers in declaration order.
30
+ * @returns declared rows followed by live routes with no declaration.
31
+ */
32
+ export declare function joinProviderDirectory(registered: readonly LlmProviderInfo[], directory: readonly LlmConfigurableProvider[]): ProviderDirectoryEntry[];
33
+ /**
34
+ * Every Remote wire face the Models page reaches.
35
+ */
36
+ export interface ModelsWire {
37
+ /** The settings Remote namespace: the redacted read and the profile writes. */
38
+ settings: SettingsRemote;
39
+ /** Credential state and writes for the references provider profiles name. */
40
+ credentials: ModelsCredentials;
41
+ /** Provider directory reads and draft endpoint discovery. */
42
+ llm: ModelsLlm;
43
+ }
44
+ /** One provider row the page renders. */
45
+ export interface ProviderRow {
46
+ /** The directory entry (route id, display name, settings address, live state). */
47
+ entry: ProviderDirectoryEntry;
48
+ /** Whether any layer configures this provider (its profile resolves). */
49
+ configured: boolean;
50
+ /** Whether the user layer alone carries the profile (removal restores the base). */
51
+ removable: boolean;
52
+ /** The credential reference the resolved profile names, when one does. */
53
+ apiKeyEnv: string | undefined;
54
+ /** Credential state for {@link apiKeyEnv}, once described. */
55
+ credential: CredentialInfo | undefined;
56
+ /**
57
+ * Credential state for the page's derived `<ROUTE>_API_KEY`, described only
58
+ * while the profile names no reference — the provider-card seat's
59
+ * `keyConfigured` fact for dormant and keyless rows, matching the editor's
60
+ * own derivation rule.
61
+ */
62
+ derivedCredential?: CredentialInfo;
63
+ }
64
+ /** Page snapshot. */
65
+ export interface ModelsSettingsState {
66
+ status: 'idle' | 'loading' | 'ready' | 'error';
67
+ /** Whole-load failure text; row-level write failures stay in the editor. */
68
+ error: string | null;
69
+ /** Credential enrichment failure; provider/settings rows remain usable. */
70
+ credentialError: string | null;
71
+ /** Whether the settings provider accepts writes. */
72
+ writable: boolean;
73
+ /** Every configurable provider joined with its configured/credential state. */
74
+ rows: readonly ProviderRow[];
75
+ /** Namespace views by ns, for the editor's schema/layers/secrets. */
76
+ namespaces: ReadonlyMap<string, SettingsNamespaceView>;
77
+ }
78
+ /**
79
+ * Human text for a rejected wire call. A transport failure rejects with an
80
+ * Error; a host or a runtime can reject with anything, and the page still has
81
+ * to say something.
82
+ * @param error - the rejection value.
83
+ * @returns the message to show.
84
+ */
85
+ export declare function messageOf(error: unknown): string;
86
+ /**
87
+ * Derive the conventional credential reference for a provider route: the v1
88
+ * page never asks for an environment-variable name, so a typed key stores
89
+ * under this derived reference and the profile records it as `apiKeyEnv`.
90
+ * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
91
+ * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
92
+ */
93
+ export declare function deriveKeyRef(provider: string): string;
94
+ /**
95
+ * The wire protocols a hand-declared route may name, read out of the owning
96
+ * namespace's own schema. This stays a schema read rather than a wire field so
97
+ * the choices the page offers cannot drift from the ones the adapter accepts:
98
+ * both come from the same `Config`.
99
+ * @param namespace - the namespace view whose schema declares the profile shape.
100
+ * @param schema - settings schema operations.
101
+ * @returns the protocol identifiers, or an empty list when the schema has none.
102
+ */
103
+ export declare function protocolChoices(namespace: SettingsNamespaceView | undefined, schema: SettingsSchemaOperations): string[];
104
+ /** The models settings page controller (one per settings surface). */
105
+ export declare class ModelsSettingsStore {
106
+ private readonly api;
107
+ private readonly schema;
108
+ private readonly describeFace;
109
+ /** The snapshot the section renders from (uSES-safe store). */
110
+ readonly store: SnapshotStore<ModelsSettingsState>;
111
+ /** Latest load wins; an older response never overwrites a newer one. */
112
+ private generation;
113
+ /**
114
+ * @param api - the page's credentials Remote and LLM wire faces.
115
+ * @param describeFace - the shared mirror's describe face (namespace views and writability).
116
+ */
117
+ constructor(api: Pick<ModelsWire, 'credentials' | 'llm'>, schema: SettingsSchemaOperations, describeFace: SettingsDescribeFace);
118
+ /**
119
+ * Refresh the whole page snapshot: the provider directory and the mirror's
120
+ * settings answer in parallel, then one batched credential describe over
121
+ * every referenced ref. Provider failure or absence of an initial settings
122
+ * answer keeps the last good rows and surfaces an error; a failed settings
123
+ * refresh reuses the mirror's held view.
124
+ * @returns nothing; the snapshot carries the outcome.
125
+ */
126
+ load(): Promise<void>;
127
+ }
128
+ /**
129
+ * Whether a joined row can serve model requests as it stands: the route is
130
+ * registered with the adapter registry, and whatever credential its resolved
131
+ * profile names is stored. A profile naming no reference authenticates through
132
+ * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
133
+ * nothing), as does a live route with no settings address at all, so neither
134
+ * owes this page a key.
135
+ * @param row - one joined provider row.
136
+ * @returns whether the user already has this provider to talk to.
137
+ */
138
+ export declare function providerUsable(row: ProviderRow): boolean;
139
+ /** First-run onboarding readiness derived only from the shared Models join. */
140
+ export type OnboardingReadiness = {
141
+ kind: 'loading';
142
+ } | {
143
+ kind: 'adapter-absent';
144
+ } | {
145
+ kind: 'provider-ready';
146
+ } | {
147
+ kind: 'credential-missing';
148
+ } | {
149
+ kind: 'unavailable';
150
+ reason: 'load-failed' | 'provider-inactive' | 'credentials-unavailable' | 'settings-read-only' | 'credential-read-only';
151
+ };
152
+ /**
153
+ * Project first-run readiness from the provider/settings/credential join used
154
+ * by the Models page. The step exists to leave the user with a model to talk
155
+ * to, so ANY usable provider ends it; only when none exists does the official
156
+ * DeepSeek route — the one route the prompt can offer a key field for — decide
157
+ * whether prompting can help. A missing official configurable-provider
158
+ * declaration means the adapter is not repairable by navigating to Models.
159
+ * @param state - current shared Models join snapshot.
160
+ * @returns the onboarding state without reading a parallel fact source.
161
+ */
162
+ export declare function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness;
163
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Welcome-notice state derived from the welcome settings scope. The scope is
3
+ * the transport: a loopback browser follows the durable Host section, while a
4
+ * remote browser's memory-mode scope never answers and the acknowledgement
5
+ * stays process-local here.
6
+ */
7
+ import { type SnapshotStore } from '@prettier-ai/dsh-client-store';
8
+ import type { SettingsScope } from '@prettier-ai/dsh-client-ui-settings/client';
9
+ /** State rendered by the welcome step. */
10
+ export interface WelcomeNoticeState {
11
+ status: 'idle' | 'loading' | 'ready' | 'saving' | 'error';
12
+ acknowledged: boolean;
13
+ error: string | null;
14
+ }
15
+ /** The welcome section as the notice reads it. */
16
+ export type WelcomeSection = Record<string, unknown>;
17
+ /**
18
+ * Accept any object section verbatim; a malformed durable value reads as an
19
+ * empty section, so the notice treats it as unacknowledged instead of leaving
20
+ * the scope stuck on its previous value.
21
+ * @param section - the wire section value.
22
+ * @returns the section object, or an empty one for non-object values.
23
+ */
24
+ export declare function decodeWelcomeSection(section: unknown): WelcomeSection;
25
+ /** Coordinates durable Host acknowledgement or a process-local remote fallback. */
26
+ export declare class WelcomeNoticeStore {
27
+ private readonly scope;
28
+ /** uSES-safe state source shared by the registered welcome step. */
29
+ readonly store: SnapshotStore<WelcomeNoticeState>;
30
+ private localAcknowledged;
31
+ private saving;
32
+ private following;
33
+ /**
34
+ * @param scope - the welcome settings namespace scope; its memory mode is
35
+ * what keeps a remote browser process-local.
36
+ */
37
+ constructor(scope: SettingsScope<WelcomeSection>);
38
+ /**
39
+ * Begin following the bound scope (idempotent) and publish its current answer.
40
+ * @returns settlement after the current answer is published.
41
+ */
42
+ load(): Promise<void>;
43
+ /**
44
+ * Persist this copy version, or advance only this process for a remote
45
+ * browser. Success is judged against the state the write left behind, so a
46
+ * refused or failed write reports false after its recovery read settles.
47
+ * @returns true when the selected persistence mode holds the acknowledgement.
48
+ */
49
+ acknowledge(): Promise<boolean>;
50
+ /** Stop following the scope. */
51
+ dispose(): void;
52
+ private derive;
53
+ }
54
+ //# sourceMappingURL=welcome-store.d.ts.map
@@ -0,0 +1,4 @@
1
+ /** Host loader entry for the browser implementation exported from `./client`. */
2
+ /** Host plugin body — no host-side behavior for the models settings plugin. */
3
+ export declare function apply(): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@prettier-ai/dsh-client-ui-settings-models`.
3
+ * @module @prettier-ai/dsh-client-ui-settings-models/invariant
4
+ */
5
+ import type { Context } from '@prettier-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "client-ui-settings-models-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1,10 @@
1
+ /** Durable settings namespace for product-wide GUI onboarding facts. */
2
+ export declare const WELCOME_NOTICE_SETTINGS_NAMESPACE = "ui-onboarding";
3
+ /** Field storing the last welcome notice version the user acknowledged. */
4
+ export declare const WELCOME_NOTICE_ACK_FIELD = "welcomeNoticeVersion";
5
+ /**
6
+ * Bump only when the notice changes materially and every user should see it
7
+ * again. The acknowledgement is compared for exact equality.
8
+ */
9
+ export declare const WELCOME_NOTICE_VERSION = "2026-08-13.1";
10
+ //# sourceMappingURL=onboarding-copy.d.ts.map
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@prettier-ai/dsh-client-ui-settings-models",
3
+ "description": "Models settings and shared product-onboarding dialogs over existing settings and credential joins",
4
+ "version": "0.1.2-alpha.1",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/client/ui-settings-models"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./invariant": {
22
+ "types": "./lib/types/invariant.d.ts",
23
+ "default": "./lib/invariant.js"
24
+ },
25
+ "./client": {
26
+ "types": "./lib/types/client/index.d.ts",
27
+ "default": "./lib/client.js"
28
+ },
29
+ "./src/*": "./src/*",
30
+ "./package.json": "./package.json"
31
+ },
32
+ "dsh": {
33
+ "client": {
34
+ "inject": [
35
+ "@prettier-ai/dsh-client-ui-settings",
36
+ "@prettier-ai/dsh-client-locale",
37
+ "@prettier-ai/dsh-api-remotes"
38
+ ],
39
+ "platform": "web"
40
+ }
41
+ },
42
+ "license": "MIT",
43
+ "peerDependencies": {
44
+ "@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
45
+ "@prettier-ai/cordis": "^4.0.1",
46
+ "@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
47
+ "@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.1",
48
+ "@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1",
49
+ "@prettier-ai/dsh-invariants": "^0.1.2-alpha.1"
50
+ },
51
+ "devDependencies": {
52
+ "@types/react": "~18.3.1",
53
+ "react": "^18.2.0",
54
+ "@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
55
+ "@prettier-ai/dsh-client-store": "^0.1.2-alpha.1",
56
+ "@prettier-ai/dsh-client-locale": "^0.1.2-alpha.1",
57
+ "@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.1",
58
+ "@prettier-ai/dsh-client-ui-settings": "^0.1.2-alpha.1",
59
+ "@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.1",
60
+ "@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.1",
61
+ "@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
62
+ "@prettier-ai/cordis": "^4.0.1",
63
+ "@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.1"
64
+ },
65
+ "files": [
66
+ "lib/index.js",
67
+ "lib/invariant.js",
68
+ "lib/client.js",
69
+ "lib/types/**/*.d.ts"
70
+ ],
71
+ "scripts": {
72
+ "bundle": "tsdown",
73
+ "watch": "tsdown --watch"
74
+ }
75
+ }