@g9tm/aiassistant-svelte 0.0.0-stage → 1.0.0
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/README.md +29 -2
- package/dist/AssistantRoot.svelte +118 -0
- package/dist/AssistantRoot.svelte.d.ts +13 -0
- package/dist/admin.d.ts +2 -0
- package/dist/admin.js +2 -0
- package/dist/blocks/BlockView.svelte +74 -0
- package/dist/blocks/BlockView.svelte.d.ts +7 -0
- package/dist/blocks/Chart.svelte +51 -0
- package/dist/blocks/Chart.svelte.d.ts +9 -0
- package/dist/browser.d.ts +16 -0
- package/dist/browser.js +80 -0
- package/dist/cards/ApprovalCard.svelte +56 -0
- package/dist/cards/ApprovalCard.svelte.d.ts +7 -0
- package/dist/cards/Cards.svelte +55 -0
- package/dist/cards/Cards.svelte.d.ts +11 -0
- package/dist/cards/SecretField.svelte +21 -0
- package/dist/cards/SecretField.svelte.d.ts +6 -0
- package/dist/context.d.ts +33 -0
- package/dist/context.js +35 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +32 -0
- package/dist/pages/Abilities.svelte +6 -0
- package/dist/pages/Abilities.svelte.d.ts +6 -0
- package/dist/pages/ActionsPage.svelte +6 -0
- package/dist/pages/ActionsPage.svelte.d.ts +6 -0
- package/dist/pages/AdminPage.svelte +53 -0
- package/dist/pages/AdminPage.svelte.d.ts +6 -0
- package/dist/pages/FindingsPage.svelte +6 -0
- package/dist/pages/FindingsPage.svelte.d.ts +6 -0
- package/dist/pages/History.svelte +6 -0
- package/dist/pages/History.svelte.d.ts +6 -0
- package/dist/pages/KnowledgePage.svelte +6 -0
- package/dist/pages/KnowledgePage.svelte.d.ts +6 -0
- package/dist/pages/LearnedPage.svelte +6 -0
- package/dist/pages/LearnedPage.svelte.d.ts +6 -0
- package/dist/pages/Page.svelte +88 -0
- package/dist/pages/Page.svelte.d.ts +8 -0
- package/dist/pages/RoutineWizard.svelte +6 -0
- package/dist/pages/RoutineWizard.svelte.d.ts +6 -0
- package/dist/pages/admin/AdminAudit.svelte +33 -0
- package/dist/pages/admin/AdminAudit.svelte.d.ts +3 -0
- package/dist/pages/admin/AdminCapabilities.svelte +91 -0
- package/dist/pages/admin/AdminCapabilities.svelte.d.ts +3 -0
- package/dist/pages/admin/AdminConnections.svelte +58 -0
- package/dist/pages/admin/AdminConnections.svelte.d.ts +6 -0
- package/dist/pages/admin/AdminFeedback.svelte +38 -0
- package/dist/pages/admin/AdminFeedback.svelte.d.ts +3 -0
- package/dist/pages/admin/AdminModels.svelte +103 -0
- package/dist/pages/admin/AdminModels.svelte.d.ts +6 -0
- package/dist/pages/admin/AdminUsage.svelte +92 -0
- package/dist/pages/admin/AdminUsage.svelte.d.ts +3 -0
- package/dist/parts/Composer.svelte +69 -0
- package/dist/parts/Composer.svelte.d.ts +14 -0
- package/dist/parts/Message.svelte +40 -0
- package/dist/parts/Message.svelte.d.ts +9 -0
- package/dist/parts/MessageList.svelte +28 -0
- package/dist/parts/MessageList.svelte.d.ts +9 -0
- package/dist/parts/RevealText.svelte +26 -0
- package/dist/parts/RevealText.svelte.d.ts +7 -0
- package/dist/parts/Small.svelte +24 -0
- package/dist/parts/Small.svelte.d.ts +10 -0
- package/dist/parts/StagesThinking.svelte +15 -0
- package/dist/parts/StagesThinking.svelte.d.ts +8 -0
- package/dist/parts/TextView.svelte +36 -0
- package/dist/parts/TextView.svelte.d.ts +6 -0
- package/dist/parts/ThinkingOrb.svelte +7 -0
- package/dist/parts/ThinkingOrb.svelte.d.ts +18 -0
- package/dist/parts/WorkCard.svelte +41 -0
- package/dist/parts/WorkCard.svelte.d.ts +7 -0
- package/dist/slots/Dialog.svelte +20 -0
- package/dist/slots/Dialog.svelte.d.ts +9 -0
- package/dist/slots/PinPad.svelte +6 -0
- package/dist/slots/PinPad.svelte.d.ts +7 -0
- package/dist/store.svelte.d.ts +15 -0
- package/dist/store.svelte.js +31 -0
- package/dist/surfaces/AssistantChat.svelte +31 -0
- package/dist/surfaces/AssistantChat.svelte.d.ts +6 -0
- package/dist/surfaces/AssistantPanel.svelte +49 -0
- package/dist/surfaces/AssistantPanel.svelte.d.ts +13 -0
- package/dist/surfaces/Surfaces.svelte +43 -0
- package/dist/surfaces/Surfaces.svelte.d.ts +16 -0
- package/dist/theme.d.ts +9 -0
- package/dist/theme.js +22 -0
- package/package.json +46 -3
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The default PinPad slot: a numeric code field (a host may give its own).
|
|
3
|
+
let { value = $bindable(""), label }: { value?: string; label: string } = $props();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<input class="g9a-pin" type="password" inputmode="numeric" autocomplete="one-time-code" aria-label={label} placeholder={label} bind:value />
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** The core assistant's snapshot as Svelte state (runes). */
|
|
2
|
+
import type { Assistant, AssistantSnapshot } from "@g9tm/aiassistant";
|
|
3
|
+
export declare class AssistantState {
|
|
4
|
+
current: AssistantSnapshot;
|
|
5
|
+
private readonly stop;
|
|
6
|
+
constructor(assistant: Assistant);
|
|
7
|
+
dispose(): void;
|
|
8
|
+
}
|
|
9
|
+
/** A clock that ticks while something is shown (for elapsed time and reveal), never during server rendering. */
|
|
10
|
+
export declare class Ticker {
|
|
11
|
+
now: number;
|
|
12
|
+
private handle;
|
|
13
|
+
start(ms?: number): void;
|
|
14
|
+
stop(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** The core assistant's snapshot as Svelte state (runes). */
|
|
2
|
+
export class AssistantState {
|
|
3
|
+
constructor(assistant) {
|
|
4
|
+
this.current = $state();
|
|
5
|
+
this.current = assistant.snapshot();
|
|
6
|
+
this.stop = assistant.subscribe((s) => {
|
|
7
|
+
this.current = s;
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
dispose() {
|
|
11
|
+
this.stop();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** A clock that ticks while something is shown (for elapsed time and reveal), never during server rendering. */
|
|
15
|
+
export class Ticker {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.now = $state(Date.now());
|
|
18
|
+
}
|
|
19
|
+
start(ms = 80) {
|
|
20
|
+
if (typeof window === "undefined" || this.handle !== undefined)
|
|
21
|
+
return;
|
|
22
|
+
this.handle = setInterval(() => {
|
|
23
|
+
this.now = Date.now();
|
|
24
|
+
}, ms);
|
|
25
|
+
}
|
|
26
|
+
stop() {
|
|
27
|
+
if (this.handle !== undefined)
|
|
28
|
+
clearInterval(this.handle);
|
|
29
|
+
this.handle = undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The chat: a composition of exported parts only (mode banner, messages, work card, composer). A host can build the
|
|
3
|
+
// same from the parts, or replace any of them.
|
|
4
|
+
import { onDestroy } from "svelte";
|
|
5
|
+
import { cls, override, useUi } from "../context.js";
|
|
6
|
+
import { AssistantState } from "../store.svelte.js";
|
|
7
|
+
import Composer from "../parts/Composer.svelte";
|
|
8
|
+
import MessageList from "../parts/MessageList.svelte";
|
|
9
|
+
import Small from "../parts/Small.svelte";
|
|
10
|
+
import WorkCard from "../parts/WorkCard.svelte";
|
|
11
|
+
|
|
12
|
+
let { placeholder = undefined }: { placeholder?: string | undefined } = $props();
|
|
13
|
+
const ui = useUi();
|
|
14
|
+
const live = new AssistantState(ui.assistant);
|
|
15
|
+
onDestroy(() => live.dispose());
|
|
16
|
+
const List = $derived(override(ui, "MessageList") ?? MessageList);
|
|
17
|
+
const Work = $derived(override(ui, "WorkCard") ?? WorkCard);
|
|
18
|
+
const Compose = $derived(override(ui, "Composer") ?? Composer);
|
|
19
|
+
const s = $derived(live.current);
|
|
20
|
+
$effect(() => {
|
|
21
|
+
ui.assistant.stateWatch.start();
|
|
22
|
+
});
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div class={cls(ui, "chat")}>
|
|
26
|
+
<Small kind="mode" state={s.state} />
|
|
27
|
+
<List messages={s.messages} plans={s.plans} runId={s.run?.runId ?? null} />
|
|
28
|
+
{#if s.run}<Work run={s.run} />{/if}
|
|
29
|
+
{#if s.error}<div class="g9a-note" role="alert">{ui.texts.t(s.error)}</div>{/if}
|
|
30
|
+
<Compose busy={s.busy} attachments={s.attachments} {placeholder} />
|
|
31
|
+
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// The panel in six layouts (sheet, side, fullscreen, inline, card, compact) or "auto" by the container's width; the
|
|
3
|
+
// layout can change live without losing the conversation. Escape closes; Alt+A (by key position, so it works with a
|
|
4
|
+
// Persian keyboard) toggles. Dialogs inside sit above the panel.
|
|
5
|
+
import type { Snippet } from "svelte";
|
|
6
|
+
import { pickLayout, type Layout, type LayoutThresholds } from "@g9tm/aiassistant";
|
|
7
|
+
import { cls, sty, useUi } from "../context.js";
|
|
8
|
+
import AssistantChat from "./AssistantChat.svelte";
|
|
9
|
+
|
|
10
|
+
let { open = $bindable(true), layout = "auto", thresholds = undefined, title = undefined, header = undefined, onclose = undefined }: {
|
|
11
|
+
open?: boolean; layout?: Layout; thresholds?: LayoutThresholds | undefined; title?: string | undefined; header?: Snippet | undefined; onclose?: (() => void) | undefined;
|
|
12
|
+
} = $props();
|
|
13
|
+
const ui = useUi();
|
|
14
|
+
const t = ui.texts.t;
|
|
15
|
+
let width = $state(1024);
|
|
16
|
+
let opener: Element | null = null;
|
|
17
|
+
const current = $derived(pickLayout(layout, width, thresholds));
|
|
18
|
+
|
|
19
|
+
function close(): void {
|
|
20
|
+
open = false;
|
|
21
|
+
onclose?.();
|
|
22
|
+
if (opener instanceof HTMLElement) opener.focus(); // focus goes back to what opened it
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function onkey(e: KeyboardEvent): void {
|
|
26
|
+
if (e.altKey && e.code === "KeyA") {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
if (!open) opener = document.activeElement;
|
|
29
|
+
open = !open;
|
|
30
|
+
} else if (e.key === "Escape" && open && current !== "inline" && current !== "card") close();
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<svelte:window onkeydown={onkey} />
|
|
35
|
+
|
|
36
|
+
<div class="g9a-measure" bind:clientWidth={width}></div>
|
|
37
|
+
{#if open || current === "inline" || current === "card"}
|
|
38
|
+
<section class={cls(ui, "panel")} style={sty(ui, "panel") ?? ""} data-layout={current} role={current === "sheet" || current === "fullscreen" ? "dialog" : "region"}
|
|
39
|
+
aria-label={title ?? t("assistant.name")} style:z-index={current === "inline" || current === "card" ? undefined : ui.layer - 1}>
|
|
40
|
+
{#if current !== "compact"}
|
|
41
|
+
<header class={cls(ui, "panel.header")}>
|
|
42
|
+
{#if header}{@render header()}{:else}<strong>{title ?? t("assistant.name")}</strong>{/if}
|
|
43
|
+
<button type="button" onclick={() => ui.assistant.fresh()}>{t("panel.new")}</button>
|
|
44
|
+
{#if current !== "inline" && current !== "card"}<button type="button" aria-label={t("panel.close")} onclick={close}>×</button>{/if}
|
|
45
|
+
</header>
|
|
46
|
+
{/if}
|
|
47
|
+
<div class={cls(ui, "panel.body")}><AssistantChat /></div>
|
|
48
|
+
</section>
|
|
49
|
+
{/if}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import { type Layout, type LayoutThresholds } from "@g9tm/aiassistant";
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
open?: boolean;
|
|
5
|
+
layout?: Layout;
|
|
6
|
+
thresholds?: LayoutThresholds | undefined;
|
|
7
|
+
title?: string | undefined;
|
|
8
|
+
header?: Snippet | undefined;
|
|
9
|
+
onclose?: (() => void) | undefined;
|
|
10
|
+
};
|
|
11
|
+
declare const AssistantPanel: import("svelte").Component<$$ComponentProps, {}, "open">;
|
|
12
|
+
type AssistantPanel = ReturnType<typeof AssistantPanel>;
|
|
13
|
+
export default AssistantPanel;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type SurfaceKind = "hero" | "bar-button" | "ask-about";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
// Small surfaces: the dashboard hero (greeting, one status line, three starts, a place to write), the bar button with
|
|
7
|
+
// the count of cards waiting, and "ask the assistant" about one thing.
|
|
8
|
+
import { onDestroy } from "svelte";
|
|
9
|
+
import { cls, useUi } from "../context.js";
|
|
10
|
+
import { AssistantState } from "../store.svelte.js";
|
|
11
|
+
|
|
12
|
+
let { kind, greeting = "", starts = [], subject = undefined, onopen = undefined }: {
|
|
13
|
+
kind: SurfaceKind; greeting?: string; starts?: string[]; subject?: { label: string; pageId: string; kind?: string; id?: string } | undefined; onopen?: (() => void) | undefined;
|
|
14
|
+
} = $props();
|
|
15
|
+
const ui = useUi();
|
|
16
|
+
const t = ui.texts.t;
|
|
17
|
+
const live = new AssistantState(ui.assistant);
|
|
18
|
+
onDestroy(() => live.dispose());
|
|
19
|
+
let text = $state("");
|
|
20
|
+
|
|
21
|
+
async function ask(q: string): Promise<void> {
|
|
22
|
+
if (!q.trim()) return;
|
|
23
|
+
const page = subject ? { pageId: subject.pageId, ...(subject.kind ? { subjectKind: subject.kind } : {}), ...(subject.id ? { subjectId: subject.id } : {}), subjectLabel: subject.label } : undefined;
|
|
24
|
+
await ui.assistant.send(q, page);
|
|
25
|
+
text = "";
|
|
26
|
+
onopen?.();
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#if kind === "hero"}
|
|
31
|
+
<div class={cls(ui, "hero")}>
|
|
32
|
+
<h2>{greeting || t("assistant.name")}</h2>
|
|
33
|
+
{#if live.current.state.mode !== "on"}<p class="g9a-note">{t(live.current.state.mode === "off" ? "mode.off" : "mode.offline")}</p>{/if}
|
|
34
|
+
<div class={cls(ui, "block.actions")}>{#each starts.slice(0, 3) as s (s)}<button type="button" class={cls(ui, "block.action")} onclick={() => ask(s)}>{s}</button>{/each}</div>
|
|
35
|
+
<form onsubmit={(e) => { e.preventDefault(); void ask(text); }}><input bind:value={text} placeholder={t("composer.placeholder")} aria-label={t("composer.placeholder")} /></form>
|
|
36
|
+
</div>
|
|
37
|
+
{:else if kind === "bar-button"}
|
|
38
|
+
<button type="button" class={cls(ui, "bar-button")} onclick={() => onopen?.()} aria-label={t("assistant.name")}>
|
|
39
|
+
{t("assistant.name")}{#if live.current.state.waiting > 0}<span class="g9a-badge">{live.current.state.waiting}</span>{/if}
|
|
40
|
+
</button>
|
|
41
|
+
{:else}
|
|
42
|
+
<button type="button" class={cls(ui, "ask-about")} onclick={() => ask(subject?.label ?? "")}>{t("assistant.name")}: {subject?.label ?? ""}</button>
|
|
43
|
+
{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type SurfaceKind = "hero" | "bar-button" | "ask-about";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
kind: SurfaceKind;
|
|
4
|
+
greeting?: string;
|
|
5
|
+
starts?: string[];
|
|
6
|
+
subject?: {
|
|
7
|
+
label: string;
|
|
8
|
+
pageId: string;
|
|
9
|
+
kind?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
} | undefined;
|
|
12
|
+
onopen?: (() => void) | undefined;
|
|
13
|
+
};
|
|
14
|
+
declare const Surfaces: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type Surfaces = ReturnType<typeof Surfaces>;
|
|
16
|
+
export default Surfaces;
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens in three levels (layer 2): base (colours, sizes), semantic (surface, accent, danger) and per
|
|
3
|
+
* component (approvalCard.border). Every value is a CSS variable the host can set; none is global.
|
|
4
|
+
*/
|
|
5
|
+
import type { AssistantTheme } from "@g9tm/aiassistant";
|
|
6
|
+
export declare const LIGHT: Readonly<Record<string, string>>;
|
|
7
|
+
export declare const DARK: Readonly<Record<string, string>>;
|
|
8
|
+
/** The CSS variables of a theme (the host's tokens over the defaults of its mode). */
|
|
9
|
+
export declare function themeVars(theme: AssistantTheme): string;
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design tokens in three levels (layer 2): base (colours, sizes), semantic (surface, accent, danger) and per
|
|
3
|
+
* component (approvalCard.border). Every value is a CSS variable the host can set; none is global.
|
|
4
|
+
*/
|
|
5
|
+
export const LIGHT = {
|
|
6
|
+
"surface": "#ffffff", "surface-2": "#f6f4f1", "ink": "#22201d", "muted": "#6b6660", "line": "#e4ded6",
|
|
7
|
+
"accent": "#8a4b2a", "accent-ink": "#ffffff", "danger": "#b42318", "ok": "#1f7a3d", "warn": "#a35a00",
|
|
8
|
+
"radius": "10px", "radius-s": "6px", "gap": "8px", "pad": "12px", "font": "inherit", "font-size": "14px",
|
|
9
|
+
"shadow": "0 6px 24px rgba(0,0,0,.12)", "motion": "180ms",
|
|
10
|
+
"approval-card-border": "var(--g9a-accent)", "chart-bar": "var(--g9a-accent)", "chart-grid": "var(--g9a-line)",
|
|
11
|
+
};
|
|
12
|
+
export const DARK = {
|
|
13
|
+
...LIGHT,
|
|
14
|
+
"surface": "#1d1b19", "surface-2": "#272421", "ink": "#efeae4", "muted": "#a39c94", "line": "#3a3632",
|
|
15
|
+
"accent": "#e0a074", "accent-ink": "#1d1b19", "shadow": "0 6px 24px rgba(0,0,0,.5)",
|
|
16
|
+
};
|
|
17
|
+
/** The CSS variables of a theme (the host's tokens over the defaults of its mode). */
|
|
18
|
+
export function themeVars(theme) {
|
|
19
|
+
const base = theme.mode === "dark" ? DARK : LIGHT;
|
|
20
|
+
const all = new Map([...Object.entries(base), ...Object.entries(theme.tokens)]);
|
|
21
|
+
return [...all].map(([k, v]) => "--g9a-" + k.replace(/[^a-z0-9-]/giu, "-") + ":" + v.replace(/[;{}]/gu, "")).join(";");
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g9tm/aiassistant-svelte",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Svelte 5 components for the G9 AI assistant, fully customisable (layouts, tokens, per-part classes, overrides, parts).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Iman Kari",
|
|
8
|
+
"url": "G9TM"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"svelte": "./dist/index.js",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./admin": {
|
|
21
|
+
"types": "./dist/admin.d.ts",
|
|
22
|
+
"svelte": "./dist/admin.js",
|
|
23
|
+
"import": "./dist/admin.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@g9tm/aiassistant": "1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@sveltejs/package": "2.5.8",
|
|
38
|
+
"svelte": "5.57.3",
|
|
39
|
+
"svelte-check": "4.7.8"
|
|
40
|
+
},
|
|
41
|
+
"svelte": "./dist/index.js",
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"svelte": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "svelte-package -i src -o dist",
|
|
47
|
+
"typecheck": "svelte-check --tsconfig ./tsconfig.json --threshold error"
|
|
48
|
+
}
|
|
6
49
|
}
|