@happyvertical/smrt-prompts 0.51.21 → 0.51.29
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/AGENTS.md +34 -1
- package/README.md +148 -2
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/cache.d.ts +33 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/collections/PromptOverrideCollection.d.ts +45 -0
- package/dist/collections/PromptOverrideCollection.d.ts.map +1 -0
- package/dist/index.d.ts +12 -174
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +298 -30
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +117 -28
- package/dist/models/PromptOverride.d.ts +32 -0
- package/dist/models/PromptOverride.d.ts.map +1 -0
- package/dist/prompt-override-service.d.ts +56 -0
- package/dist/prompt-override-service.d.ts.map +1 -0
- package/dist/prompt-registry.d.ts +13 -0
- package/dist/prompt-registry.d.ts.map +1 -0
- package/dist/prompt-resolver.d.ts +3 -0
- package/dist/prompt-resolver.d.ts.map +1 -0
- package/dist/prompt-settings.d.ts +188 -0
- package/dist/prompt-settings.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +108 -248
- package/dist/svelte/components/PromptSettingsPanel.svelte +353 -0
- package/dist/svelte/components/PromptSettingsPanel.svelte.d.ts +52 -0
- package/dist/svelte/components/PromptSettingsPanel.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +14 -0
- package/dist/svelte/types.d.ts +75 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +42 -0
- package/dist/types.d.ts +107 -110
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +29 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +27 -8
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* PromptSettingsPanel — the shared prompt-management surface.
|
|
4
|
+
*
|
|
5
|
+
* Purely presentational: it takes rows and callbacks. It does no fetching, and
|
|
6
|
+
* it makes no authorization decision — the host decides who may see the panel
|
|
7
|
+
* and who may write, and enforces that on the server (see
|
|
8
|
+
* `PromptSettingsService` and `PromptOverrideService`). Rendering the app
|
|
9
|
+
* column is a host decision too: apps with no platform-admin tier omit it.
|
|
10
|
+
*
|
|
11
|
+
* Each row renders as its own `<form>`, so a SvelteKit host can point
|
|
12
|
+
* `formAction` at a form action and get a working screen with no client JS:
|
|
13
|
+
* the "override" checkbox and the textarea are independent fields, and
|
|
14
|
+
* whether a scope is overridden is decided by whether its checkbox's name is
|
|
15
|
+
* present in the submitted `FormData` — never by disabling the textarea,
|
|
16
|
+
* which a plain HTML submit could not re-enable. Supplying `onSave` instead
|
|
17
|
+
* intercepts the submit and hands the host the same decision.
|
|
18
|
+
*/
|
|
19
|
+
import { Badge, Button, Card } from '@happyvertical/smrt-ui/ui';
|
|
20
|
+
import type { PromptSettingsChange, PromptSettingsView } from '../types.js';
|
|
21
|
+
import {
|
|
22
|
+
appRevertPreview,
|
|
23
|
+
isTemplateEditable,
|
|
24
|
+
supplyingLevelLabel,
|
|
25
|
+
tenantRevertPreview,
|
|
26
|
+
} from '../types.js';
|
|
27
|
+
|
|
28
|
+
export interface Props {
|
|
29
|
+
/** The prompts to manage, in the order they should be rendered. */
|
|
30
|
+
prompts?: PromptSettingsView[];
|
|
31
|
+
/** Column heading for the tenant-scope editor. */
|
|
32
|
+
tenantLabel?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Render the app-scope column. Off by default: an app with no
|
|
35
|
+
* platform-admin tier has nothing to put there.
|
|
36
|
+
*/
|
|
37
|
+
showApp?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Let the operator change the app column. Ignored unless `showApp`. When
|
|
40
|
+
* false the column is rendered read-only, which is how a tenant admin sees
|
|
41
|
+
* the app-wide default their own override is layered on.
|
|
42
|
+
*/
|
|
43
|
+
appEditable?: boolean;
|
|
44
|
+
/** Column heading for the app-scope editor. */
|
|
45
|
+
appLabel?: string;
|
|
46
|
+
/** Disable every control while a save is in flight. */
|
|
47
|
+
busy?: boolean;
|
|
48
|
+
/** Success text to show above the list. */
|
|
49
|
+
message?: string | null;
|
|
50
|
+
/** Error text to show above the list. */
|
|
51
|
+
error?: string | null;
|
|
52
|
+
/** Text for the empty state. */
|
|
53
|
+
emptyMessage?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Identity of what is being edited (typically the tenant id). Unsaved edits
|
|
56
|
+
* are discarded whenever this changes — or, when it is omitted, whenever
|
|
57
|
+
* `prompts` is replaced with a new array, which is what a reloaded server
|
|
58
|
+
* load produces. Without that, a row edited for one tenant would carry its
|
|
59
|
+
* unsaved text into the next tenant's rows under the same key.
|
|
60
|
+
*/
|
|
61
|
+
contextKey?: unknown;
|
|
62
|
+
/** Label for each row's submit control. */
|
|
63
|
+
saveLabel?: string;
|
|
64
|
+
/**
|
|
65
|
+
* SvelteKit form action for each row's `<form>` (e.g. `?/savePrompt`). Omit
|
|
66
|
+
* when driving the panel entirely through {@link Props.onSave}.
|
|
67
|
+
*/
|
|
68
|
+
formAction?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Called with the requested change instead of submitting the form. The host
|
|
71
|
+
* performs its own permission check and the write.
|
|
72
|
+
*/
|
|
73
|
+
onSave?: (change: PromptSettingsChange) => void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const {
|
|
77
|
+
prompts = [],
|
|
78
|
+
tenantLabel = 'Tenant override',
|
|
79
|
+
showApp = false,
|
|
80
|
+
appEditable = false,
|
|
81
|
+
appLabel = 'App override',
|
|
82
|
+
busy = false,
|
|
83
|
+
contextKey,
|
|
84
|
+
message = null,
|
|
85
|
+
error = null,
|
|
86
|
+
emptyMessage = 'No prompts are registered yet. Definitions appear here once they are registered from code.',
|
|
87
|
+
saveLabel = 'Save',
|
|
88
|
+
formAction,
|
|
89
|
+
onSave,
|
|
90
|
+
}: Props = $props();
|
|
91
|
+
|
|
92
|
+
const appIsEditable = $derived(showApp && appEditable);
|
|
93
|
+
const canSubmit = $derived(!busy && (onSave != null || formAction != null));
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Remount the rows when the editing context changes, discarding unsaved
|
|
97
|
+
* edits. Without this an operator's unsaved text would survive a reload or a
|
|
98
|
+
* tenant switch and then be submitted against the new rows.
|
|
99
|
+
*/
|
|
100
|
+
const resetKey = $derived(contextKey ?? prompts);
|
|
101
|
+
|
|
102
|
+
function submit(event: SubmitEvent, prompt: PromptSettingsView): void {
|
|
103
|
+
// A non-editable row's controls are disabled, and disabled controls are
|
|
104
|
+
// absent from FormData — a submit would read as "unchecked" and revert an
|
|
105
|
+
// existing override. Such a row is read-only: it never submits.
|
|
106
|
+
if (!isTemplateEditable(prompt)) {
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!onSave) return;
|
|
111
|
+
event.preventDefault();
|
|
112
|
+
const fields = new FormData(event.currentTarget as HTMLFormElement);
|
|
113
|
+
const change: PromptSettingsChange = {
|
|
114
|
+
key: prompt.key,
|
|
115
|
+
tenantTemplate: fields.has('tenantOverride')
|
|
116
|
+
? String(fields.get('tenantTemplate') ?? '')
|
|
117
|
+
: null,
|
|
118
|
+
};
|
|
119
|
+
if (appIsEditable) {
|
|
120
|
+
change.appTemplate = fields.has('appOverride')
|
|
121
|
+
? String(fields.get('appTemplate') ?? '')
|
|
122
|
+
: null;
|
|
123
|
+
}
|
|
124
|
+
onSave(change);
|
|
125
|
+
}
|
|
126
|
+
</script>
|
|
127
|
+
|
|
128
|
+
<section class="prompt-settings" data-testid="prompt-settings-panel">
|
|
129
|
+
{#if message}
|
|
130
|
+
<p class="ps-flash" role="status">{message}</p>
|
|
131
|
+
{/if}
|
|
132
|
+
{#if error}
|
|
133
|
+
<p class="ps-flash ps-flash-error" role="alert">{error}</p>
|
|
134
|
+
{/if}
|
|
135
|
+
|
|
136
|
+
{#key resetKey}
|
|
137
|
+
{#each prompts as prompt (prompt.key)}
|
|
138
|
+
<Card variant="outlined">
|
|
139
|
+
<div class="ps-row">
|
|
140
|
+
<div class="ps-copy">
|
|
141
|
+
<div class="ps-title-row">
|
|
142
|
+
<h3 class="ps-title">{prompt.description || prompt.key}</h3>
|
|
143
|
+
<Badge variant="default" size="sm">
|
|
144
|
+
{supplyingLevelLabel(prompt.supplyingLevel)}
|
|
145
|
+
</Badge>
|
|
146
|
+
</div>
|
|
147
|
+
<code class="ps-key">{prompt.key}</code>
|
|
148
|
+
<pre class="ps-effective">{prompt.effectiveTemplate}</pre>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<form
|
|
152
|
+
class="ps-controls"
|
|
153
|
+
method="POST"
|
|
154
|
+
action={formAction}
|
|
155
|
+
onsubmit={(event) => submit(event, prompt)}
|
|
156
|
+
>
|
|
157
|
+
<input type="hidden" name="key" value={prompt.key} />
|
|
158
|
+
|
|
159
|
+
{#if showApp}
|
|
160
|
+
{#if appIsEditable}
|
|
161
|
+
<div class="ps-field">
|
|
162
|
+
<label class="ps-toggle">
|
|
163
|
+
<input
|
|
164
|
+
type="checkbox"
|
|
165
|
+
name="appOverride"
|
|
166
|
+
checked={prompt.appTemplate != null}
|
|
167
|
+
disabled={busy || !isTemplateEditable(prompt)}
|
|
168
|
+
/>
|
|
169
|
+
{appLabel}
|
|
170
|
+
</label>
|
|
171
|
+
<textarea
|
|
172
|
+
class="ps-textarea"
|
|
173
|
+
name="appTemplate"
|
|
174
|
+
aria-label={appLabel}
|
|
175
|
+
rows="3"
|
|
176
|
+
disabled={busy || !isTemplateEditable(prompt)}
|
|
177
|
+
value={prompt.appTemplate ?? appRevertPreview(prompt)}
|
|
178
|
+
></textarea>
|
|
179
|
+
<p class="ps-hint">
|
|
180
|
+
Unchecked reverts to: {appRevertPreview(prompt)}
|
|
181
|
+
</p>
|
|
182
|
+
</div>
|
|
183
|
+
{:else}
|
|
184
|
+
<div class="ps-field">
|
|
185
|
+
<span class="ps-field-label">{appLabel}</span>
|
|
186
|
+
<p class="ps-readonly">
|
|
187
|
+
{prompt.appTemplate ?? appRevertPreview(prompt)}
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
{/if}
|
|
191
|
+
{/if}
|
|
192
|
+
|
|
193
|
+
<div class="ps-field">
|
|
194
|
+
<label class="ps-toggle">
|
|
195
|
+
<input
|
|
196
|
+
type="checkbox"
|
|
197
|
+
name="tenantOverride"
|
|
198
|
+
checked={prompt.tenantTemplate != null}
|
|
199
|
+
disabled={busy || !isTemplateEditable(prompt)}
|
|
200
|
+
/>
|
|
201
|
+
{tenantLabel}
|
|
202
|
+
</label>
|
|
203
|
+
<textarea
|
|
204
|
+
class="ps-textarea"
|
|
205
|
+
name="tenantTemplate"
|
|
206
|
+
aria-label={tenantLabel}
|
|
207
|
+
rows="4"
|
|
208
|
+
disabled={busy || !isTemplateEditable(prompt)}
|
|
209
|
+
value={prompt.tenantTemplate ?? tenantRevertPreview(prompt)}
|
|
210
|
+
></textarea>
|
|
211
|
+
<p class="ps-hint">
|
|
212
|
+
Unchecked reverts to: {tenantRevertPreview(prompt)}
|
|
213
|
+
</p>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<Button
|
|
217
|
+
type="submit"
|
|
218
|
+
variant="primary"
|
|
219
|
+
size="sm"
|
|
220
|
+
disabled={!canSubmit || !isTemplateEditable(prompt)}
|
|
221
|
+
>
|
|
222
|
+
{saveLabel}
|
|
223
|
+
</Button>
|
|
224
|
+
</form>
|
|
225
|
+
</div>
|
|
226
|
+
</Card>
|
|
227
|
+
{:else}
|
|
228
|
+
<p class="ps-empty">{emptyMessage}</p>
|
|
229
|
+
{/each}
|
|
230
|
+
{/key}
|
|
231
|
+
</section>
|
|
232
|
+
|
|
233
|
+
<style>
|
|
234
|
+
.prompt-settings {
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-direction: column;
|
|
237
|
+
gap: 1rem;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.ps-flash {
|
|
241
|
+
margin: 0;
|
|
242
|
+
padding: 0.625rem 0.75rem;
|
|
243
|
+
border-radius: 0.375rem;
|
|
244
|
+
background: var(--color-surface-muted, #f3f4f6);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.ps-flash-error {
|
|
248
|
+
color: var(--color-error-text, #991b1b);
|
|
249
|
+
background: var(--color-error-surface, #fef2f2);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.ps-empty {
|
|
253
|
+
margin: 0;
|
|
254
|
+
color: var(--color-text-muted, #6b7280);
|
|
255
|
+
font-style: italic;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.ps-row {
|
|
259
|
+
display: grid;
|
|
260
|
+
grid-template-columns: minmax(0, 1fr) minmax(18rem, 26rem);
|
|
261
|
+
gap: 1rem;
|
|
262
|
+
align-items: start;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.ps-copy {
|
|
266
|
+
min-width: 0;
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: column;
|
|
269
|
+
gap: 0.25rem;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.ps-title-row {
|
|
273
|
+
display: flex;
|
|
274
|
+
align-items: center;
|
|
275
|
+
justify-content: space-between;
|
|
276
|
+
gap: 0.5rem;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.ps-title {
|
|
280
|
+
margin: 0;
|
|
281
|
+
font-size: 1rem;
|
|
282
|
+
line-height: 1.25;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.ps-key {
|
|
286
|
+
font-size: 0.8125rem;
|
|
287
|
+
color: var(--color-text-muted, #6b7280);
|
|
288
|
+
overflow-wrap: anywhere;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.ps-effective {
|
|
292
|
+
margin: 0;
|
|
293
|
+
padding: 0.5rem;
|
|
294
|
+
border-radius: 0.375rem;
|
|
295
|
+
background: var(--color-surface-muted, #f3f4f6);
|
|
296
|
+
white-space: pre-wrap;
|
|
297
|
+
overflow-wrap: anywhere;
|
|
298
|
+
font-family: inherit;
|
|
299
|
+
font-size: 0.875rem;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.ps-controls {
|
|
303
|
+
display: flex;
|
|
304
|
+
flex-direction: column;
|
|
305
|
+
gap: 0.75rem;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.ps-field {
|
|
309
|
+
min-width: 0;
|
|
310
|
+
display: flex;
|
|
311
|
+
flex-direction: column;
|
|
312
|
+
gap: 0.25rem;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.ps-field-label {
|
|
316
|
+
font-size: 0.8125rem;
|
|
317
|
+
color: var(--color-text-muted, #6b7280);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.ps-toggle {
|
|
321
|
+
display: flex;
|
|
322
|
+
align-items: center;
|
|
323
|
+
gap: 0.375rem;
|
|
324
|
+
font-size: 0.8125rem;
|
|
325
|
+
color: var(--color-text-muted, #6b7280);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.ps-textarea {
|
|
329
|
+
width: 100%;
|
|
330
|
+
padding: 0.5rem;
|
|
331
|
+
border: 1px solid var(--color-border, #d1d5db);
|
|
332
|
+
border-radius: 0.375rem;
|
|
333
|
+
background: var(--color-surface, #fff);
|
|
334
|
+
color: inherit;
|
|
335
|
+
font: inherit;
|
|
336
|
+
resize: vertical;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.ps-hint,
|
|
340
|
+
.ps-readonly {
|
|
341
|
+
margin: 0;
|
|
342
|
+
font-size: 0.8125rem;
|
|
343
|
+
color: var(--color-text-muted, #6b7280);
|
|
344
|
+
line-height: 1.45;
|
|
345
|
+
overflow-wrap: anywhere;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@media (max-width: 860px) {
|
|
349
|
+
.ps-row {
|
|
350
|
+
grid-template-columns: 1fr;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
</style>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { PromptSettingsChange, PromptSettingsView } from '../types.js';
|
|
2
|
+
export interface Props {
|
|
3
|
+
/** The prompts to manage, in the order they should be rendered. */
|
|
4
|
+
prompts?: PromptSettingsView[];
|
|
5
|
+
/** Column heading for the tenant-scope editor. */
|
|
6
|
+
tenantLabel?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Render the app-scope column. Off by default: an app with no
|
|
9
|
+
* platform-admin tier has nothing to put there.
|
|
10
|
+
*/
|
|
11
|
+
showApp?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Let the operator change the app column. Ignored unless `showApp`. When
|
|
14
|
+
* false the column is rendered read-only, which is how a tenant admin sees
|
|
15
|
+
* the app-wide default their own override is layered on.
|
|
16
|
+
*/
|
|
17
|
+
appEditable?: boolean;
|
|
18
|
+
/** Column heading for the app-scope editor. */
|
|
19
|
+
appLabel?: string;
|
|
20
|
+
/** Disable every control while a save is in flight. */
|
|
21
|
+
busy?: boolean;
|
|
22
|
+
/** Success text to show above the list. */
|
|
23
|
+
message?: string | null;
|
|
24
|
+
/** Error text to show above the list. */
|
|
25
|
+
error?: string | null;
|
|
26
|
+
/** Text for the empty state. */
|
|
27
|
+
emptyMessage?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Identity of what is being edited (typically the tenant id). Unsaved edits
|
|
30
|
+
* are discarded whenever this changes — or, when it is omitted, whenever
|
|
31
|
+
* `prompts` is replaced with a new array, which is what a reloaded server
|
|
32
|
+
* load produces. Without that, a row edited for one tenant would carry its
|
|
33
|
+
* unsaved text into the next tenant's rows under the same key.
|
|
34
|
+
*/
|
|
35
|
+
contextKey?: unknown;
|
|
36
|
+
/** Label for each row's submit control. */
|
|
37
|
+
saveLabel?: string;
|
|
38
|
+
/**
|
|
39
|
+
* SvelteKit form action for each row's `<form>` (e.g. `?/savePrompt`). Omit
|
|
40
|
+
* when driving the panel entirely through {@link Props.onSave}.
|
|
41
|
+
*/
|
|
42
|
+
formAction?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Called with the requested change instead of submitting the form. The host
|
|
45
|
+
* performs its own permission check and the write.
|
|
46
|
+
*/
|
|
47
|
+
onSave?: (change: PromptSettingsChange) => void;
|
|
48
|
+
}
|
|
49
|
+
declare const PromptSettingsPanel: import("svelte").Component<Props, {}, "">;
|
|
50
|
+
type PromptSettingsPanel = ReturnType<typeof PromptSettingsPanel>;
|
|
51
|
+
export default PromptSettingsPanel;
|
|
52
|
+
//# sourceMappingURL=PromptSettingsPanel.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptSettingsPanel.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/PromptSettingsPanel.svelte.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAS5E,MAAM,WAAW,KAAK;IACpB,mEAAmE;IACnE,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACjD;AAuID,QAAA,MAAM,mBAAmB,2CAAwC,CAAC;AAClE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @happyvertical/smrt-prompts/svelte
|
|
3
|
+
*
|
|
4
|
+
* Optional Svelte 5 UI for prompt management. Presentational only: the panel
|
|
5
|
+
* takes rows and callbacks, does no fetching, and makes no authorization
|
|
6
|
+
* decision. Hosts render it from a server load that used
|
|
7
|
+
* `PromptSettingsService` and wire saves to their own permission-checked
|
|
8
|
+
* route. The root `@happyvertical/smrt-prompts` export stays Svelte-free.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import type { ComponentProps } from 'svelte';
|
|
13
|
+
import PromptSettingsPanel from './components/PromptSettingsPanel.svelte';
|
|
14
|
+
export { PromptSettingsPanel };
|
|
15
|
+
export type PromptSettingsPanelProps = ComponentProps<typeof PromptSettingsPanel>;
|
|
16
|
+
export { appRevertPreview, isTemplateEditable, type PromptSettingsChange, type PromptSettingsSupplyingLevel, type PromptSettingsView, supplyingLevelLabel, tenantRevertPreview, } from './types.js';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,mBAAmB,MAAM,yCAAyC,CAAC;AAE1E,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,MAAM,MAAM,wBAAwB,GAAG,cAAc,CACnD,OAAO,mBAAmB,CAC3B,CAAC;AAEF,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EACvB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @happyvertical/smrt-prompts/svelte
|
|
3
|
+
*
|
|
4
|
+
* Optional Svelte 5 UI for prompt management. Presentational only: the panel
|
|
5
|
+
* takes rows and callbacks, does no fetching, and makes no authorization
|
|
6
|
+
* decision. Hosts render it from a server load that used
|
|
7
|
+
* `PromptSettingsService` and wire saves to their own permission-checked
|
|
8
|
+
* route. The root `@happyvertical/smrt-prompts` export stays Svelte-free.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import PromptSettingsPanel from './components/PromptSettingsPanel.svelte';
|
|
13
|
+
export { PromptSettingsPanel };
|
|
14
|
+
export { appRevertPreview, isTemplateEditable, supplyingLevelLabel, tenantRevertPreview, } from './types.js';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentational types for the prompt management UI.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately free of the `@smrt()` model classes and of `@happyvertical/smrt-core`
|
|
5
|
+
* so the Svelte bundle stays a thin presentation layer. Field names match
|
|
6
|
+
* `PromptSettingsRow` produced by `PromptSettingsService.listPromptSettings()`,
|
|
7
|
+
* so a row is structurally assignable to {@link PromptSettingsView} with no
|
|
8
|
+
* mapping step.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/** Which level supplied a prompt's effective template. */
|
|
13
|
+
export type PromptSettingsSupplyingLevel = 'default' | 'config' | 'app' | 'tenant';
|
|
14
|
+
/** A render-ready view of one prompt's settings. */
|
|
15
|
+
export interface PromptSettingsView {
|
|
16
|
+
/**
|
|
17
|
+
* The persisted identifier. Shown verbatim so an operator can correlate the
|
|
18
|
+
* row with code — renaming a key orphans its overrides, so it is stable
|
|
19
|
+
* enough to quote.
|
|
20
|
+
*/
|
|
21
|
+
key: string;
|
|
22
|
+
/** Human description; falls back to the key when empty. */
|
|
23
|
+
description?: string;
|
|
24
|
+
/** The text actually in effect for the requested tenant (unrendered). */
|
|
25
|
+
effectiveTemplate: string;
|
|
26
|
+
/** Which level supplied {@link effectiveTemplate}. */
|
|
27
|
+
supplyingLevel?: PromptSettingsSupplyingLevel;
|
|
28
|
+
/** Whether a stored override may change the template; hides the editor when `false`. */
|
|
29
|
+
editable?: {
|
|
30
|
+
template?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** The app-level override's text, or `null`/absent when there is none. */
|
|
33
|
+
appTemplate?: string | null;
|
|
34
|
+
/** The tenant-level override's text, or `null`/absent when there is none. */
|
|
35
|
+
tenantTemplate?: string | null;
|
|
36
|
+
/** What the **app** scope's "revert to default" produces. */
|
|
37
|
+
appDefaultTemplate?: string;
|
|
38
|
+
/**
|
|
39
|
+
* What the **tenant** scope's "revert to default" produces. `null`/absent
|
|
40
|
+
* when not known (e.g. no tenant was requested) — the panel then falls back
|
|
41
|
+
* to {@link appDefaultTemplate} or {@link effectiveTemplate} rather than
|
|
42
|
+
* claiming a value nothing computed.
|
|
43
|
+
*/
|
|
44
|
+
inheritedTemplate?: string | null;
|
|
45
|
+
}
|
|
46
|
+
/** One override change requested from the panel. */
|
|
47
|
+
export interface PromptSettingsChange {
|
|
48
|
+
/** The prompt the operator was editing. */
|
|
49
|
+
key: string;
|
|
50
|
+
/**
|
|
51
|
+
* Requested tenant-scope text, or `null` to revert (return the tenant scope
|
|
52
|
+
* to whatever it inherits).
|
|
53
|
+
*/
|
|
54
|
+
tenantTemplate: string | null;
|
|
55
|
+
/**
|
|
56
|
+
* Requested app-scope text, or `null` to revert — present only when the
|
|
57
|
+
* panel rendered an editable app column.
|
|
58
|
+
*/
|
|
59
|
+
appTemplate?: string | null;
|
|
60
|
+
}
|
|
61
|
+
/** Human label for {@link PromptSettingsView.supplyingLevel}. */
|
|
62
|
+
export declare function supplyingLevelLabel(level: PromptSettingsSupplyingLevel | undefined): string;
|
|
63
|
+
/**
|
|
64
|
+
* What the tenant scope's "revert to default" control returns to: the app
|
|
65
|
+
* override if there is one, otherwise the config/registry value. Falls back to
|
|
66
|
+
* {@link PromptSettingsView.effectiveTemplate} only when the row supplies
|
|
67
|
+
* neither computed fallback (e.g. a minimal test fixture), rather than
|
|
68
|
+
* rendering nothing.
|
|
69
|
+
*/
|
|
70
|
+
export declare function tenantRevertPreview(view: PromptSettingsView): string;
|
|
71
|
+
/** What the app scope's "revert to default" control returns to. */
|
|
72
|
+
export declare function appRevertPreview(view: PromptSettingsView): string;
|
|
73
|
+
/** Whether the panel may offer an editor for this prompt's template at all. */
|
|
74
|
+
export declare function isTemplateEditable(view: PromptSettingsView): boolean;
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/svelte/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,4BAA4B,GACpC,SAAS,GACT,QAAQ,GACR,KAAK,GACL,QAAQ,CAAC;AAEb,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,cAAc,CAAC,EAAE,4BAA4B,CAAC;IAC9C,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAClC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6DAA6D;IAC7D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,4BAA4B,GAAG,SAAS,GAC9C,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAIpE;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAEjE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAEpE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentational types for the prompt management UI.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately free of the `@smrt()` model classes and of `@happyvertical/smrt-core`
|
|
5
|
+
* so the Svelte bundle stays a thin presentation layer. Field names match
|
|
6
|
+
* `PromptSettingsRow` produced by `PromptSettingsService.listPromptSettings()`,
|
|
7
|
+
* so a row is structurally assignable to {@link PromptSettingsView} with no
|
|
8
|
+
* mapping step.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
/** Human label for {@link PromptSettingsView.supplyingLevel}. */
|
|
13
|
+
export function supplyingLevelLabel(level) {
|
|
14
|
+
switch (level) {
|
|
15
|
+
case 'tenant':
|
|
16
|
+
return 'Tenant override';
|
|
17
|
+
case 'app':
|
|
18
|
+
return 'App override';
|
|
19
|
+
case 'config':
|
|
20
|
+
return 'Config override';
|
|
21
|
+
default:
|
|
22
|
+
return 'Registry default';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* What the tenant scope's "revert to default" control returns to: the app
|
|
27
|
+
* override if there is one, otherwise the config/registry value. Falls back to
|
|
28
|
+
* {@link PromptSettingsView.effectiveTemplate} only when the row supplies
|
|
29
|
+
* neither computed fallback (e.g. a minimal test fixture), rather than
|
|
30
|
+
* rendering nothing.
|
|
31
|
+
*/
|
|
32
|
+
export function tenantRevertPreview(view) {
|
|
33
|
+
return (view.inheritedTemplate ?? view.appDefaultTemplate ?? view.effectiveTemplate);
|
|
34
|
+
}
|
|
35
|
+
/** What the app scope's "revert to default" control returns to. */
|
|
36
|
+
export function appRevertPreview(view) {
|
|
37
|
+
return view.appDefaultTemplate ?? view.effectiveTemplate;
|
|
38
|
+
}
|
|
39
|
+
/** Whether the panel may offer an editor for this prompt's template at all. */
|
|
40
|
+
export function isTemplateEditable(view) {
|
|
41
|
+
return view.editable?.template !== false;
|
|
42
|
+
}
|