@skaile/forge-settings 1.0.0 → 1.0.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/ai-sdk/index.d.ts +3 -2
  4. package/dist/runtime/ai-sdk/index.js +3 -11
  5. package/dist/runtime/editor/index.js +4 -15
  6. package/dist/runtime/model/errors.d.ts +8 -0
  7. package/dist/runtime/model/errors.js +9 -0
  8. package/dist/runtime/server/credential-policy.d.ts +2 -1
  9. package/dist/runtime/server/credential-policy.js +1 -0
  10. package/dist/runtime/server/credential-store.js +1 -1
  11. package/dist/runtime/server/env-layers.js +1 -3
  12. package/dist/runtime/server/provider-discovery.js +1 -1
  13. package/dist/runtime/server/provider-layers.js +1 -3
  14. package/dist/runtime/server/provider-write.js +2 -4
  15. package/dist/runtime/shared/guards.d.ts +2 -0
  16. package/dist/runtime/shared/guards.js +3 -0
  17. package/dist/runtime/vue/providers-panel-model.d.ts +147 -0
  18. package/dist/runtime/vue/providers-panel-model.js +37 -0
  19. package/dist/runtime/vue/useProvidersPanel.d.ts +5 -122
  20. package/dist/runtime/vue/useProvidersPanel.js +15 -37
  21. package/package.json +1 -1
  22. package/src/runtime/ai-sdk/index.ts +9 -12
  23. package/src/runtime/editor/index.ts +4 -15
  24. package/src/runtime/model/errors.ts +21 -0
  25. package/src/runtime/server/credential-policy.ts +3 -1
  26. package/src/runtime/server/credential-store.ts +1 -1
  27. package/src/runtime/server/env-layers.ts +1 -4
  28. package/src/runtime/server/provider-discovery.ts +1 -1
  29. package/src/runtime/server/provider-layers.ts +1 -4
  30. package/src/runtime/server/provider-write.ts +2 -7
  31. package/src/runtime/shared/guards.ts +4 -0
  32. package/src/runtime/vue/providers-panel-model.ts +203 -0
  33. package/src/runtime/vue/useProvidersPanel.ts +35 -192
@@ -39,198 +39,41 @@ import {
39
39
  type AIProviderSurface,
40
40
  validateCredentialRef,
41
41
  } from "../shared/provider-registry";
42
-
43
- // ── Types ─────────────────────────────────────────────────────────────────────
44
-
45
- /** Registry document a provider entry is defined in. */
46
- export type ProvidersPanelLayer = "instance" | "workspace";
47
-
48
- /** Props both `ForgeProvidersPanel` variants declare. */
49
- export interface ProvidersPanelProps {
50
- /** `GET` merged view for this scope (`/api/providers` | `/api/workspaces/:id/providers`). */
51
- providersUrl: string;
52
- /** `PUT|DELETE ${providersWriteUrl}/:id`; `GET ${providersWriteUrl}/detected`. */
53
- providersWriteUrl: string;
54
- /** Catalog preset summaries. Default `/api/providers/presets`. */
55
- presetsUrl?: string;
56
- /**
57
- * The scope's `.env` route. `GET` on load and after every write; keys typed
58
- * into the panel write through it. Omitted, no key can be entered.
59
- */
60
- environmentUrl?: string;
61
- /** The scope's own registry document. */
62
- layer: ProvidersPanelLayer;
63
- /** Disables every write (non-admin at instance scope; provider lock). */
64
- readOnly?: boolean;
65
- }
66
-
67
- /** Emits both variants declare. */
68
- export type ProvidersPanelEmit = (event: "changed") => void;
69
-
70
- /** One entry of `GET ${providersUrl}?all=1`. */
71
- export interface ProvidersPanelEntry {
72
- id: string;
73
- /** The entry's label, else its id. */
74
- name: string;
75
- kind: AIProviderKind;
76
- /** Whether the credential reference resolved on the server. */
77
- configured: boolean;
78
- /** Why it did not resolve. Secret-free. */
79
- error?: string;
80
- credentialRef?: string;
81
- credentialKind?: AIProviderCredentialKind;
82
- hasEnvKey: boolean;
83
- envKeyName?: string;
84
- baseUrl?: string;
85
- preset?: string;
86
- surface?: AIProviderSurface;
87
- enabled: boolean;
88
- locked: boolean;
89
- /** Registry documents holding the id, lowest first: `["instance"]`, `["workspace"]` or both. */
90
- layers: ProvidersPanelLayer[];
91
- /** The scope's own document's values for the editable fields the dialog does not show. */
92
- layerFields?: Record<string, unknown>;
93
- }
94
-
95
- /** One catalog preset, as `GET /api/providers/presets` and `.../detected` list it. */
96
- export interface ProvidersPanelPreset {
97
- id: string;
98
- label: string;
99
- kind: AIProviderKind;
100
- surface?: AIProviderSurface;
101
- base_url?: string;
102
- base_url_env?: string;
103
- credential: { kind: AIProviderCredentialKind; env?: string };
104
- }
105
-
106
- /** Where a row's entry lives relative to the scope's own document. */
107
- export type ProvidersPanelRowState = "own" | "inherited" | "patched";
108
-
109
- /** One entry of a row's credential select. */
110
- export interface ProvidersPanelCredentialOption {
111
- /** An env var NAME, a literal non-env ref, {@link CREDENTIAL_ENTER_KEY} or {@link CREDENTIAL_OTHER_REF}. */
112
- value: string;
113
- /** `NAME ••••hint` | `NAME (not set)` | the literal ref | `Enter a key…` | `Other reference…`. */
114
- label: string;
115
- defined?: boolean;
116
- hint?: string;
117
- source?: EnvLayerId;
118
- action?: "enter-key" | "other-ref";
119
- }
120
-
121
- /** A table row: the entry plus what the panel derives for it. */
122
- export interface ProvidersPanelRow extends ProvidersPanelEntry {
123
- /** Own entry, an inherited one, or an inherited one this scope patched. */
124
- state: ProvidersPanelRowState;
125
- /** `instance` | `workspace` | `instance · overridden here`. */
126
- badge: string;
127
- /** Set on inherited rows. */
128
- inheritedNote?: string;
129
- /** Edit/Delete offered: the scope's document defines it and the panel is writable. */
130
- editable: boolean;
131
- /** Reset offered: a patched row of a writable panel. */
132
- canReset: boolean;
133
- /** The enabled switch is live. */
134
- canToggle: boolean;
135
- /** The entry takes a credential (its kind is not `none`). */
136
- needsCredential: boolean;
137
- /** The credential picker is live. */
138
- canEditCredential: boolean;
139
- /** The select's model: the env var NAME of an `env:` ref, else the literal ref, else `""`. */
140
- credentialValue: string;
141
- credentialOptions: ProvidersPanelCredentialOption[];
142
- /** The preset it inherits, else its surface, else its kind. */
143
- origin: string;
144
- /** `configured · <source>`, `missing <VAR>`, the resolver's reason, or `No credential needed.`. */
145
- status: string;
146
- /** Which other layer defines or overrides the credential; see the panel contract. */
147
- overrideNotices: string[];
148
- }
149
-
150
- /** The add/edit dialog's fields. */
151
- export interface ProvidersPanelForm {
152
- /** A preset id, or {@link CUSTOM_PRESET}. */
153
- preset: string;
154
- id: string;
155
- /** Custom entries only. */
156
- surface: string;
157
- /** Empty: the preset's endpoint. */
158
- baseUrl: string;
159
- /** Adding only: the `env:` variable the credential references. */
160
- envName: string;
161
- /** Adding only, "Set value now": written to the scope's `.env`, never to the provider route. */
162
- secret: string;
163
- }
164
-
165
- // ── Constants ─────────────────────────────────────────────────────────────────
166
-
167
- /** The preset select's value for an entry that names no preset. */
168
- export const CUSTOM_PRESET = "__custom__";
169
-
170
- /** Credential select value: open the inline key editor. */
171
- export const CREDENTIAL_ENTER_KEY = "__enter_key__";
172
-
173
- /** Credential select value: open the inline reference editor. */
174
- export const CREDENTIAL_OTHER_REF = "__other_ref__";
175
-
176
- /** Registry ids the write routes accept (`isSafeProviderId` upstream). */
177
- const PROVIDER_ID_PATTERN = /^[a-z0-9][a-z0-9_-]*$/;
178
-
179
- const DEFAULT_PRESETS_URL = "/api/providers/presets";
180
-
181
- /** An `env:NAME` credential reference; group 1 is the variable name. */
182
- const ENV_REF_PATTERN = /^env:(.+)$/;
183
-
184
- /** The credential kind a written reference gets when the row states none. */
185
- const FALLBACK_CREDENTIAL_KIND: AIProviderCredentialKind = "api_key_header";
186
-
187
- const ENV_SOURCE_LABEL: Record<EnvLayerId, string> = {
188
- instance: "instance .env",
189
- workspace: "workspace .env",
190
- process: "boot environment",
191
- };
192
-
193
- const OVERRIDES_INSTANCE_NOTICE =
194
- "Entering a key here stores it in this workspace's .env and overrides that value for this workspace.";
195
-
196
- /**
197
- * The server's refusal for a failed request, else `fallback`. A registry
198
- * rejection (`400` with `data.diagnostics`) reads as its diagnostics' messages.
199
- */
200
- function requestErrorMessage(err: unknown, fallback: string): string {
201
- const e = err as {
202
- data?: { statusMessage?: unknown; data?: { diagnostics?: Array<{ message?: unknown }> } };
203
- statusMessage?: unknown;
204
- } | null;
205
- const details = (e?.data?.data?.diagnostics ?? [])
206
- .map((d) => d.message)
207
- .filter((m): m is string => typeof m === "string" && m !== "");
208
- if (details.length > 0) return details.join("; ");
209
- const message = e?.data?.statusMessage ?? e?.statusMessage;
210
- return typeof message === "string" && message ? message : fallback;
211
- }
212
-
213
- /** The variable name of an `env:NAME` reference. */
214
- function envNameOfRef(ref: string | undefined): string | undefined {
215
- return ref ? ENV_REF_PATTERN.exec(ref)?.[1] : undefined;
216
- }
217
-
218
- /** `configured · …` for a reference that is not an env var. */
219
- function nonEnvSourceLabel(ref: string): string | undefined {
220
- if (ref.startsWith("keyring:")) return "keyring";
221
- if (ref.startsWith("cmd:")) return "runtime-owned (cmd)";
222
- if (ref.startsWith("platform:")) return "control-plane-owned (platform)";
223
- return undefined;
224
- }
225
-
226
- const EMPTY_FORM: Readonly<ProvidersPanelForm> = {
227
- preset: "",
228
- id: "",
229
- surface: "",
230
- baseUrl: "",
231
- envName: "",
232
- secret: "",
233
- };
42
+ import {
43
+ CREDENTIAL_ENTER_KEY,
44
+ CREDENTIAL_OTHER_REF,
45
+ CUSTOM_PRESET,
46
+ DEFAULT_PRESETS_URL,
47
+ EMPTY_FORM,
48
+ ENV_SOURCE_LABEL,
49
+ envNameOfRef,
50
+ FALLBACK_CREDENTIAL_KIND,
51
+ nonEnvSourceLabel,
52
+ OVERRIDES_INSTANCE_NOTICE,
53
+ PROVIDER_ID_PATTERN,
54
+ type ProvidersPanelCredentialOption,
55
+ type ProvidersPanelEntry,
56
+ type ProvidersPanelEmit,
57
+ type ProvidersPanelForm,
58
+ type ProvidersPanelPreset,
59
+ type ProvidersPanelProps,
60
+ type ProvidersPanelRow,
61
+ type ProvidersPanelRowState,
62
+ requestErrorMessage,
63
+ } from "./providers-panel-model";
64
+
65
+ export { CREDENTIAL_ENTER_KEY, CREDENTIAL_OTHER_REF, CUSTOM_PRESET } from "./providers-panel-model";
66
+ export type {
67
+ ProvidersPanelCredentialOption,
68
+ ProvidersPanelEmit,
69
+ ProvidersPanelEntry,
70
+ ProvidersPanelForm,
71
+ ProvidersPanelLayer,
72
+ ProvidersPanelPreset,
73
+ ProvidersPanelProps,
74
+ ProvidersPanelRow,
75
+ ProvidersPanelRowState,
76
+ } from "./providers-panel-model";
234
77
 
235
78
  /** What both `ForgeProvidersPanel` variants bind to. */
236
79
  export interface ProvidersPanelState {