@columenlabs/lumen-ui 0.1.245 → 0.1.247
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/dist/assistant/lumen-assistant.js +4 -4
- package/dist/assistant/settings.js +5 -5
- package/dist/assistant/usage-history.d.ts +3 -1
- package/dist/assistant/usage-history.js +27 -7
- package/dist/assistant/use-assistant-chat.d.ts +5 -1
- package/dist/assistant/use-assistant-chat.js +2 -1
- package/dist/share-meter.d.ts +3 -1
- package/dist/share-meter.js +4 -4
- package/package.json +2 -2
|
@@ -22,10 +22,10 @@ import { cardsOnScreen, kindName, pointAt, sectionsOnScreen, targetEl, textOf, }
|
|
|
22
22
|
import { Alert, AlertDescription } from '../ui/alert.js';
|
|
23
23
|
import { Button } from '../ui/button.js';
|
|
24
24
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible.js';
|
|
25
|
+
import { InputGroup, InputGroupAddon, InputGroupTextarea } from '../ui/input-group.js';
|
|
25
26
|
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover.js';
|
|
26
27
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '../ui/sheet.js';
|
|
27
28
|
import { Spinner } from '../ui/spinner.js';
|
|
28
|
-
import { Textarea } from '../ui/textarea.js';
|
|
29
29
|
import { ChatImage } from './chat-image.js';
|
|
30
30
|
import { chatMarkdown, chatTurns, copyMarkdown, turnMarkdown } from './copy.js';
|
|
31
31
|
import { ImageCard, ImagePending, toolIs } from './image-card.js';
|
|
@@ -880,7 +880,7 @@ export function LumenComposer({ name, busy, queued, queue, canSteer = false, onS
|
|
|
880
880
|
const r = sourceItems.get(o.value)?.();
|
|
881
881
|
if (r)
|
|
882
882
|
setRefs((p) => [...p, r]);
|
|
883
|
-
}, onClose: () => setClosed(`${text}|${caret}`) })), quote && _jsx(QuoteLine, { quote: quote, onRemove: () => setQuote(null) }), images.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", "aria-label": "Images going with your message", children: images.map((img, i) => (_jsxs("span", { className: "relative", children: [_jsx("img", { src: imageUrl(img), alt: `Pasted ${i + 1}`, className: "size-12 rounded-md border object-cover" }), _jsx("button", { type: "button", "aria-label": `Remove image ${i + 1}`, className: "absolute -top-1.5 -right-1.5 grid size-4 place-items-center rounded-full border bg-background text-muted-foreground hover:text-foreground", onClick: () => setImages((p) => p.filter((_, j) => j !== i)), children: _jsx(XIcon, { className: "size-3" }) })] }, `${i}:${img.data.length}`))) })), (tierLabel || refs.length > 0) && (_jsxs("div", { className: "mb-2 flex flex-wrap gap-1", children: [tierLabel && (_jsx(ComposerChip, { sign: TIER, label: tierLabel, onRemove: () => setTier(null) })), refs.map((r, i) => (_jsx(ComposerChip, { sign: POINT, label: r.label, onRemove: () => setRefs((p) => p.filter((_, j) => j !== i)) }, `${r.kind}:${r.label}:${i}`)))] })), _jsxs(
|
|
883
|
+
}, onClose: () => setClosed(`${text}|${caret}`) })), quote && _jsx(QuoteLine, { quote: quote, onRemove: () => setQuote(null) }), images.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1.5", "aria-label": "Images going with your message", children: images.map((img, i) => (_jsxs("span", { className: "relative", children: [_jsx("img", { src: imageUrl(img), alt: `Pasted ${i + 1}`, className: "size-12 rounded-md border object-cover" }), _jsx("button", { type: "button", "aria-label": `Remove image ${i + 1}`, className: "absolute -top-1.5 -right-1.5 grid size-4 place-items-center rounded-full border bg-background text-muted-foreground hover:text-foreground", onClick: () => setImages((p) => p.filter((_, j) => j !== i)), children: _jsx(XIcon, { className: "size-3" }) })] }, `${i}:${img.data.length}`))) })), (tierLabel || refs.length > 0) && (_jsxs("div", { className: "mb-2 flex flex-wrap gap-1", children: [tierLabel && (_jsx(ComposerChip, { sign: TIER, label: tierLabel, onRemove: () => setTier(null) })), refs.map((r, i) => (_jsx(ComposerChip, { sign: POINT, label: r.label, onRemove: () => setRefs((p) => p.filter((_, j) => j !== i)) }, `${r.kind}:${r.label}:${i}`)))] })), _jsxs(InputGroup, { children: [_jsx(InputGroupTextarea, { ref: box, "aria-label": `Message ${name}`, placeholder: `Ask ${name}…${hints.length ? ` (${hints.join(' ')})` : ''}`, className: "max-h-48 min-h-11", value: text, disabled: disabled, onChange: (e) => {
|
|
884
884
|
setText(e.target.value);
|
|
885
885
|
setCaret(e.target.selectionStart);
|
|
886
886
|
}, onSelect: (e) => setCaret(e.currentTarget.selectionStart), onPaste: (e) => {
|
|
@@ -900,11 +900,11 @@ export function LumenComposer({ name, busy, queued, queue, canSteer = false, onS
|
|
|
900
900
|
e.preventDefault();
|
|
901
901
|
send(e.altKey ? 'queue' : undefined);
|
|
902
902
|
}
|
|
903
|
-
} }), (
|
|
903
|
+
} }), _jsxs(InputGroupAddon, { align: "block-end", className: "gap-0.5 px-1.5 pb-1.5", children: [canAttach && (_jsxs(_Fragment, { children: [_jsx(IconButton, { icon: PaperclipIcon, label: "Attach images", size: "icon-xs", disabled: disabled, onClick: () => filePick.current?.click() }), _jsx("input", { ref: filePick, type: "file", accept: "image/*", multiple: true, hidden: true, onChange: (e) => {
|
|
904
904
|
if (e.target.files)
|
|
905
905
|
attach(e.target.files);
|
|
906
906
|
e.target.value = '';
|
|
907
|
-
} })] })), modes.map((md) => (_jsx(IconButton, { icon: md.icon, label: md.label, size: "icon-xs", variant: use === md.id ? 'secondary' : 'ghost', "aria-pressed": use === md.id, className: cn(use === md.id && 'text-primary'), disabled: disabled, onClick: () => setUse((u) => (u === md.id ? null : md.id)) }, md.id)))
|
|
907
|
+
} })] })), modes.map((md) => (_jsx(IconButton, { icon: md.icon, label: md.label, size: "icon-xs", variant: use === md.id ? 'secondary' : 'ghost', "aria-pressed": use === md.id, className: cn(use === md.id && 'text-primary'), disabled: disabled, onClick: () => setUse((u) => (u === md.id ? null : md.id)) }, md.id))), _jsx("div", { className: "ml-auto", children: busy && !text.trim() ? (_jsx(IconButton, { icon: SquareIcon, label: "Stop", variant: "outline", size: "icon-xs", onClick: onStop })) : busy ? (_jsxs("span", { className: "flex gap-1", children: [_jsx(IconButton, { icon: ListPlusIcon, label: canSteer ? 'Queue for after (⌥↩)' : 'Queue for after (↩)', variant: canSteer ? 'outline' : 'default', size: "icon-xs", disabled: disabled, onClick: () => send('queue') }), canSteer && (_jsx(IconButton, { icon: CornerDownRightIcon, label: "Steer now (\u21A9)", variant: "default", size: "icon-xs", disabled: disabled, onClick: () => send('steer') }))] })) : (_jsx(IconButton, { icon: ArrowUpIcon, label: "Send", variant: "default", size: "icon-xs", disabled: !text.trim() || disabled, onClick: () => send() })) })] })] })] }));
|
|
908
908
|
}
|
|
909
909
|
/**
|
|
910
910
|
* What waits above the box while an answer runs: steering messages until the answer reads them,
|
|
@@ -170,7 +170,7 @@ function Providers({ client }) {
|
|
|
170
170
|
// is exactly what the server may pay with.
|
|
171
171
|
const rows = s.providers.filter((p) => !p.own_ways || p.own_ways.length > 0);
|
|
172
172
|
const ownSet = rows.some(ownUsable);
|
|
173
|
-
return (_jsxs("div", { className: "flex flex-col", children: [_jsx(LumenExpandList, { children: rows.map((p) => (_jsx(OwnProviderKey, { client: client, p: p }, p.id))) }), ownSet && (_jsx(SettingField, { label: "Answers run on", info: "Your own key or plan first, with the shared credits behind it; or the shared credits first.", children: _jsxs(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: s.pay, "aria-label": "Answers run on", onValueChange: (pay) => pay && void apply('pay', () => client.settings({ pay: pay })), children: [_jsx(ToggleGroupItem, { value: "own", children: "Your own first" }), _jsx(ToggleGroupItem, { value: "app", children: "Credits first" })] }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), ownSet && _jsx(OwnCapUse, { s: s }), _jsx(OwnKeyUsage, { client: client, always: ownSet })] }));
|
|
173
|
+
return (_jsxs("div", { className: "flex flex-col", children: [_jsx(LumenExpandList, { children: rows.map((p) => (_jsx(OwnProviderKey, { client: client, p: p }, p.id))) }), ownSet && (_jsx(SettingField, { label: "Answers run on", info: "Your own key or plan first, with the shared credits behind it; or the shared credits first.", children: _jsxs(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: s.pay, "aria-label": "Answers run on", onValueChange: (pay) => pay && void apply('pay', () => client.settings({ pay: pay })), children: [_jsx(ToggleGroupItem, { value: "own", children: "Your own first" }), _jsx(ToggleGroupItem, { value: "app", children: "Credits first" })] }) })), ownSet && (_jsx(SettingField, { label: "Your keys may spend", info: "On your keys, every provider together.", children: _jsx(CapInput, { label: "Your monthly cap", value: s.caps.own, onSave: (n) => void apply('own', () => client.ownCap(n)) }) })), ownSet && _jsx(OwnCapUse, { s: s }), _jsx(OwnKeyUsage, { client: client, always: ownSet, usable: rows.filter(ownUsable).map((p) => p.id) })] }));
|
|
174
174
|
} }));
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
@@ -178,14 +178,14 @@ function Providers({ client }) {
|
|
|
178
178
|
* against, so this and the switch to shared credits never disagree.
|
|
179
179
|
*/
|
|
180
180
|
function OwnCapUse({ s }) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.reduce((a, r) => a + r.usd, 0);
|
|
181
|
+
// The server's own count (key calls only, on providers still set); older servers sum own rows.
|
|
182
|
+
const used = s.spend.own_used ??
|
|
183
|
+
s.spend.rows.filter((r) => r.payer === 'own' && !r.free).reduce((a, r) => a + r.usd, 0);
|
|
184
184
|
const cap = s.caps.own;
|
|
185
185
|
const full = cap > 0 && used >= cap;
|
|
186
186
|
return (_jsx(SettingField, { label: "Used this month", info: full
|
|
187
187
|
? 'Your cap is used up, so the shared credits pay until next month or until you raise the cap.'
|
|
188
|
-
: 'What your own keys
|
|
188
|
+
: 'What your own API keys spent this month, against your cap. A plan sign-in counts nothing.', children: _jsxs("div", { className: "flex w-56 min-w-0 flex-col gap-1", children: [_jsx(ShareMeter, { value: cap > 0 ? used / cap : 1, wide: true, capped: true }), _jsxs("span", { className: "truncate text-muted-foreground text-xs", title: `${usd(used)} of ${usd(cap)}${full ? ' · Cap reached: credits pay' : ''}`, children: [_jsxs("span", { className: "num", children: [usd(used), " of ", usd(cap)] }), full && ' · Cap reached: credits pay'] })] }) }));
|
|
189
189
|
}
|
|
190
190
|
/** One provider's shared key, which an admin sets for everyone. */
|
|
191
191
|
function SharedProviderKey({ client, p }) {
|
|
@@ -18,7 +18,9 @@ export declare function UsageHistoryView({ client, className, }: {
|
|
|
18
18
|
* (Session, Date, Amount), newest first, and a Total of the rows. A session counts in the range its
|
|
19
19
|
* last use falls in. Shown when `always` (an own key or plan is set) or any session was paid on one.
|
|
20
20
|
*/
|
|
21
|
-
export declare function OwnKeyUsage({ client, always }: {
|
|
21
|
+
export declare function OwnKeyUsage({ client, always, usable, }: {
|
|
22
22
|
client: AssistantAdapter;
|
|
23
23
|
always?: boolean;
|
|
24
|
+
/** Providers the person can pay with now: earlier spend on any other is listed apart, uncounted. */
|
|
25
|
+
usable?: string[];
|
|
24
26
|
}): import("react").JSX.Element | null;
|
|
@@ -102,7 +102,7 @@ const OWN_RANGES = [
|
|
|
102
102
|
* (Session, Date, Amount), newest first, and a Total of the rows. A session counts in the range its
|
|
103
103
|
* last use falls in. Shown when `always` (an own key or plan is set) or any session was paid on one.
|
|
104
104
|
*/
|
|
105
|
-
export function OwnKeyUsage({ client, always }) {
|
|
105
|
+
export function OwnKeyUsage({ client, always, usable, }) {
|
|
106
106
|
const [range, setRange] = useState('7d');
|
|
107
107
|
const now = useAssistantUsage(client).data;
|
|
108
108
|
// The month before, for a range that reaches back past this month's start.
|
|
@@ -122,13 +122,21 @@ export function OwnKeyUsage({ client, always }) {
|
|
|
122
122
|
// This month's own spend that no chat or run carries (spent before per-chat tracking), so the
|
|
123
123
|
// table never reads "nothing" while the cap's own numbers say otherwise.
|
|
124
124
|
const tagged = now.entries.reduce((a, e) => a + (e.own_usd ?? 0), 0);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
// A plan sign-in's calls cost nothing, so they are no one's spend.
|
|
126
|
+
const ownRows = now.rows.filter((r) => r.payer === 'own' && !r.free && r.way !== 'plan');
|
|
127
|
+
const removed = usable && ownRows.length
|
|
128
|
+
? ownRows
|
|
129
|
+
.filter((r) => r.provider && !usable.includes(r.provider))
|
|
130
|
+
.reduce((a, r) => a + r.usd, 0)
|
|
131
|
+
: 0;
|
|
132
|
+
const ownMonth = ownRows.reduce((a, r) => a + r.usd, 0);
|
|
133
|
+
const left = ownMonth - tagged - removed;
|
|
134
|
+
const untracked = left >= 0.01 ? left : 0;
|
|
135
|
+
const gone = removed >= 0.01 ? removed : 0;
|
|
136
|
+
const total = sessions.reduce((a, e) => a + (e.own_usd ?? 0), 0) + untracked + gone;
|
|
130
137
|
const earlier = 'Earlier this month, not per chat';
|
|
131
|
-
|
|
138
|
+
const removedText = 'Key not in use now, not counted';
|
|
139
|
+
return (_jsxs("div", { className: "flex flex-col gap-2 border-t border-border/60 pb-3 first:border-t-0", children: [_jsx(SettingField, { label: "Spent on your keys", info: "Each chat and run your own key or plan paid for, by its last use.", className: "border-t-0", end: _jsx(ToggleGroup, { type: "single", variant: "outline", size: "sm", spacing: 0, value: range, "aria-label": "Range", onValueChange: (v) => v && setRange(v), children: OWN_RANGES.map((r) => (_jsx(ToggleGroupItem, { value: r.id, "aria-label": `Last ${r.id}`, children: r.id }, r.id))) }) }), sessions.length || untracked || gone ? (_jsx(DetailsTable, { head: [
|
|
132
140
|
{ label: 'Session', grow: true },
|
|
133
141
|
{ label: 'Date', hideOnPhone: true },
|
|
134
142
|
{ label: 'Amount', right: true },
|
|
@@ -153,5 +161,17 @@ export function OwnKeyUsage({ client, always }) {
|
|
|
153
161
|
},
|
|
154
162
|
]
|
|
155
163
|
: []),
|
|
164
|
+
...(gone
|
|
165
|
+
? [
|
|
166
|
+
{
|
|
167
|
+
key: 'removed',
|
|
168
|
+
cells: [
|
|
169
|
+
_jsx("span", { className: "block truncate text-muted-foreground", title: removedText, children: removedText }, "n"),
|
|
170
|
+
_jsx("span", {}, "t"),
|
|
171
|
+
usd(gone),
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
]
|
|
175
|
+
: []),
|
|
156
176
|
], foot: ['Total', _jsx("span", { className: "max-md:hidden" }, "d"), usd(total)] })) : (_jsxs("p", { className: "text-muted-foreground text-sm", children: ["Nothing spent on your keys in the last ", range, "."] }))] }));
|
|
157
177
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { AssistantEvent, AssistantMessage, AssistantScreenOutcome, ChatItem, ChatUsage, DraftItem, StepItem } from '@columenlabs/lumen-ui-types/assistant';
|
|
2
2
|
import type { AssistantAdapter } from './client.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* An item as the panel draws it: a text still streaming, a step still running. `writing` marks a
|
|
5
|
+
* running step whose tool makes a change at once, so an app can show what it changes as changing.
|
|
6
|
+
*/
|
|
4
7
|
export type LiveItem = ChatItem & {
|
|
5
8
|
live?: boolean;
|
|
9
|
+
writing?: boolean;
|
|
6
10
|
};
|
|
7
11
|
type Extra = Omit<AssistantMessage, 'message' | 'chat_id'>;
|
|
8
12
|
/** A message sent while an answer runs: waiting for it to end, or steered into it. */
|
|
@@ -83,6 +83,7 @@ export function applyEvent(prev, e) {
|
|
|
83
83
|
ok: true,
|
|
84
84
|
ms: 0,
|
|
85
85
|
live: true,
|
|
86
|
+
...(e.data.write ? { writing: true } : {}),
|
|
86
87
|
});
|
|
87
88
|
break;
|
|
88
89
|
case 'step': {
|
|
@@ -157,7 +158,7 @@ const settled = (items) => items.map((i) => {
|
|
|
157
158
|
return { ...i, items: settled(i.items) };
|
|
158
159
|
if (!i.live || i.kind === 'screen')
|
|
159
160
|
return i;
|
|
160
|
-
const { live: _l, ...rest } = i;
|
|
161
|
+
const { live: _l, writing: _w, ...rest } = i;
|
|
161
162
|
return rest;
|
|
162
163
|
});
|
|
163
164
|
export function useAssistantChat(client) {
|
package/dist/share-meter.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface ShareSegment {
|
|
|
8
8
|
/** Who it is, read out by screen readers and in the bar's hover (`web 122%`). */
|
|
9
9
|
label?: string;
|
|
10
10
|
}
|
|
11
|
-
export declare function ShareMeter({ value, label, color, kind, levels, segments, wide, className, }: {
|
|
11
|
+
export declare function ShareMeter({ value, label, color, kind, levels, segments, wide, capped, className, }: {
|
|
12
12
|
/** 0 to 1 fills the bar; past 1 it stays full and the overage spills past a tick at the cap. */
|
|
13
13
|
value: number;
|
|
14
14
|
/** The number beside the bar, e.g. `113%`; left out, the rounded percent. */
|
|
@@ -23,5 +23,7 @@ export declare function ShareMeter({ value, label, color, kind, levels, segments
|
|
|
23
23
|
segments?: ShareSegment[];
|
|
24
24
|
/** Fills its cell (a list row) instead of the fixed table width. */
|
|
25
25
|
wide?: boolean;
|
|
26
|
+
/** A share that stops at its cap: no spill slot, so the bar takes the whole track. */
|
|
27
|
+
capped?: boolean;
|
|
26
28
|
className?: string;
|
|
27
29
|
}): import("react").JSX.Element;
|
package/dist/share-meter.js
CHANGED
|
@@ -4,16 +4,16 @@ import { METER_LEVEL_COLOR, meterLevel } from './meter-level.js';
|
|
|
4
4
|
import { Progress } from './ui/progress.js';
|
|
5
5
|
/** How far past the cap the spill stub can grow (a share of the cap). */
|
|
6
6
|
const SPILL_MAX = 0.5;
|
|
7
|
-
export function ShareMeter({ value, label, color, kind, levels, segments, wide, className, }) {
|
|
7
|
+
export function ShareMeter({ value, label, color, kind, levels, segments, wide, capped, className, }) {
|
|
8
8
|
const said = segments
|
|
9
9
|
?.filter((s) => s.value > 0)
|
|
10
10
|
.map((s) => `${s.label ?? ''} ${Math.round(s.value * 100)}%`.trim());
|
|
11
|
-
const over = kind !== 'health' && value > 1;
|
|
11
|
+
const over = !capped && kind !== 'health' && value > 1;
|
|
12
12
|
const spill = over ? Math.min(value - 1, SPILL_MAX) / SPILL_MAX : 0;
|
|
13
13
|
return (_jsxs("span", { className: cn('inline-flex items-center gap-2', wide && 'w-full', className), title: said?.length ? said.join(' · ') : undefined, children: [_jsxs("span", { "data-slot": "share-meter", "data-over": over || undefined, className: cn('flex shrink-0 items-center', wide ? 'w-full shrink' : 'w-16'), style: {
|
|
14
14
|
'--meter-color': color ?? METER_LEVEL_COLOR[meterLevel(value, levels, kind)],
|
|
15
|
-
}, children: [_jsx(Progress, { value: Math.max(0, Math.min(value, 1)) * 100, "aria-label": said?.length ? said.join(', ') : undefined, className: cn('h-1.5 w-auto flex-2 [&>[data-slot=progress-indicator]]:bg-(--meter-color)', over && 'rounded-r-none') }), _jsx("span", { "aria-hidden": true, className:
|
|
15
|
+
}, children: [_jsx(Progress, { value: Math.max(0, Math.min(value, 1)) * 100, "aria-label": said?.length ? said.join(', ') : undefined, className: cn('h-1.5 w-auto flex-2 [&>[data-slot=progress-indicator]]:bg-(--meter-color)', over && 'rounded-r-none') }), _jsx("span", { "aria-hidden": true, className: cn('flex h-1.5 flex-1', capped && 'hidden'), children: over && (_jsx("span", { "data-slot": "share-spill", className: "h-full min-w-1 rounded-r-full border-foreground/70 border-l-2", style: {
|
|
16
16
|
width: `${spill * 100}%`,
|
|
17
17
|
background: 'repeating-linear-gradient(135deg, var(--meter-color) 0 2px, transparent 2px 4px)',
|
|
18
|
-
} })) })] }), _jsx("span", { className:
|
|
18
|
+
} })) })] }), _jsx("span", { className: cn('num shrink-0 text-right text-xs', capped ? 'w-auto' : 'w-11'), children: label ?? `${Math.round(value * 100)}%` })] }));
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@columenlabs/lumen-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.247",
|
|
4
4
|
"description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@codemirror/lang-javascript": "6.2.5",
|
|
50
50
|
"@codemirror/lang-json": "6.0.2",
|
|
51
51
|
"@codemirror/lang-sql": "6.10.0",
|
|
52
|
-
"@columenlabs/lumen-ui-types": "0.1.
|
|
52
|
+
"@columenlabs/lumen-ui-types": "0.1.247",
|
|
53
53
|
"@dnd-kit/core": "6.3.1",
|
|
54
54
|
"@dnd-kit/sortable": "10.0.0",
|
|
55
55
|
"@dnd-kit/utilities": "3.2.2",
|