wizards 0.4.0 → 0.4.2

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 (124) hide show
  1. package/apps/runtime/dist/agents/studio-assistant.js +67 -20
  2. package/apps/runtime/dist/docs/dev/plugins/reference.md +7 -4
  3. package/apps/runtime/dist/docs/dev/plugins/reloading.md +3 -3
  4. package/apps/runtime/dist/docs/dev/plugins/runners.md +9 -12
  5. package/apps/runtime/dist/docs/dev/plugins/server.md +3 -1
  6. package/apps/runtime/dist/docs/dev/plugins/space.md +19 -1
  7. package/apps/runtime/dist/docs/dev/plugins/studio.md +43 -6
  8. package/apps/runtime/dist/docs/dev/plugins/styling.md +8 -1
  9. package/apps/runtime/dist/docs/user/space.md +4 -4
  10. package/apps/runtime/dist/docs/user/test-and-share.md +22 -58
  11. package/apps/runtime/dist/engine/steps.js +3 -2
  12. package/apps/runtime/dist/engine/template.js +14 -10
  13. package/apps/runtime/dist/film/project.js +15 -3
  14. package/apps/runtime/dist/plugins/loader.js +38 -2
  15. package/apps/runtime/dist/routes/studio.js +28 -1
  16. package/apps/runtime/dist/services/brand.js +61 -1
  17. package/apps/runtime/dist/services/projects.js +19 -10
  18. package/apps/runtime/dist/tools/plugin.js +11 -3
  19. package/apps/web/dist/assets/AboutDialog-CH1rQdia.js +1 -0
  20. package/apps/web/dist/assets/{ChangelogDialog-DynvQuuR.js → ChangelogDialog-78MQLHfA.js} +1 -1
  21. package/apps/web/dist/assets/ChatView-DLJfy69U.js +10 -0
  22. package/apps/web/dist/assets/EditorPage-BYrZokVk.js +3 -0
  23. package/apps/web/dist/assets/{FlowPreview-BZLnG7GV.js → FlowPreview-xIWPdOCV.js} +1 -1
  24. package/apps/web/dist/assets/{Harness-CNh3nbB_.js → Harness-CsDhNLSW.js} +2 -2
  25. package/apps/web/dist/assets/NewWizardChannels-JB3V6DCL.js +1 -0
  26. package/apps/web/dist/assets/NewWizardPage-Bkh-hjSe.js +7 -0
  27. package/apps/web/dist/assets/OnboardingPage-Diw1ILjC.js +1 -0
  28. package/apps/web/dist/assets/ProjectPage-FgoZDzPI.js +1 -0
  29. package/apps/web/dist/assets/PublicRunner-ClT6B7t5.js +1 -0
  30. package/apps/web/dist/assets/{ReadOnly-DTjv2Jzm.js → ReadOnly-DQPHmvS0.js} +1 -1
  31. package/apps/web/dist/assets/RunDrawer-DAwTEyjM.js +4 -0
  32. package/apps/web/dist/assets/{RunnerView-BPPmlv9z.js → RunnerView-B_tJroFM.js} +1 -1
  33. package/apps/web/dist/assets/SettingsPage-BsMN-XQs.js +1 -0
  34. package/apps/web/dist/assets/SetupPage-C7FuIpSt.js +1 -0
  35. package/apps/web/dist/assets/SharePage-CbFe83L9.js +1 -0
  36. package/apps/web/dist/assets/changelog-mYclku73.js +1 -0
  37. package/apps/web/dist/assets/{circle-alert-CVOH4wAv.js → circle-alert-DCBV7n5k.js} +1 -1
  38. package/apps/web/dist/assets/{esm-BfXdeWaI.js → esm-BhIeKBJY.js} +1 -1
  39. package/apps/web/dist/assets/index-CmxVazOf.css +1 -0
  40. package/apps/web/dist/assets/index-fflYi8P1.js +14 -0
  41. package/apps/web/dist/assets/{lock-DHBh62LA.js → lock-DlzTfwxP.js} +1 -1
  42. package/apps/web/dist/assets/{phone-Bt1cyWpY.js → phone-BFD815nc.js} +1 -1
  43. package/apps/web/dist/assets/{settings-menu-ace1vI3i.js → settings-menu-C5Y8SOhG.js} +1 -1
  44. package/apps/web/dist/assets/ui-DTuixH4y.js +134 -0
  45. package/apps/web/dist/assets/{upload-CCEq88l4.js → upload-BEf5-d6X.js} +1 -1
  46. package/apps/web/dist/index.html +4 -5
  47. package/apps/web/dist/mcp/flow.html +2 -2
  48. package/node_modules/@engenty-wizards/plugin-sdk/dist/index.d.ts +36 -2
  49. package/node_modules/@engenty-wizards/plugin-sdk/dist/studio.d.ts +44 -1
  50. package/node_modules/@engenty-wizards/shared/dist/feature-flags.d.ts +18 -0
  51. package/node_modules/@engenty-wizards/shared/dist/feature-flags.js +18 -0
  52. package/node_modules/@engenty-wizards/shared/dist/projects.d.ts +22 -6
  53. package/node_modules/@engenty-wizards/shared/dist/projects.js +20 -0
  54. package/package.json +1 -1
  55. package/apps/web/dist/assets/AboutDialog-CPQiN7H9.js +0 -1
  56. package/apps/web/dist/assets/ChatView-CKo_9IZD.js +0 -10
  57. package/apps/web/dist/assets/EditorPage-CDIJXC4T.js +0 -3
  58. package/apps/web/dist/assets/NewWizardChannels-C1Ss9UMY.js +0 -1
  59. package/apps/web/dist/assets/NewWizardPage-2qLAbvDL.js +0 -7
  60. package/apps/web/dist/assets/OnboardingPage-C1FJwEsT.js +0 -1
  61. package/apps/web/dist/assets/ProjectPage-CGuLUuOs.js +0 -1
  62. package/apps/web/dist/assets/PublicRunner-BKw1lOW4.js +0 -1
  63. package/apps/web/dist/assets/RunDrawer-D1I5xqVf.js +0 -4
  64. package/apps/web/dist/assets/SettingsPage-zbomQfGy.js +0 -1
  65. package/apps/web/dist/assets/SetupPage-D3F7M6Pz.js +0 -1
  66. package/apps/web/dist/assets/SharePage-BY49IJgT.js +0 -1
  67. package/apps/web/dist/assets/changelog-DYZC2E6q.js +0 -1
  68. package/apps/web/dist/assets/index-B9xVkr2X.css +0 -1
  69. package/apps/web/dist/assets/index-BH0PYgov.js +0 -15
  70. package/apps/web/dist/assets/logo-C4V2_3Ar.js +0 -1
  71. package/apps/web/dist/assets/ui-D2SqIZeQ.js +0 -133
  72. package/modules/calls/dist/client.css +0 -3
  73. package/modules/calls/dist/client.js +0 -1
  74. package/modules/calls/engenty.plugin.json +0 -8
  75. package/modules/calls/migrations/0001_init.sql +0 -26
  76. package/modules/calls/package.json +0 -25
  77. package/modules/calls/src/openai.ts +0 -155
  78. package/modules/calls/src/plugin.ts +0 -407
  79. package/modules/calls/src/rules.ts +0 -226
  80. package/modules/calls/src/schema.ts +0 -39
  81. package/modules/calls/src/session.ts +0 -353
  82. package/modules/calls/src/store.ts +0 -124
  83. package/modules/calls/src/twilio.ts +0 -90
  84. package/modules/calls/tsconfig.json +0 -10
  85. package/modules/calls/ui/Settings.tsx +0 -137
  86. package/modules/calls/ui/app.ts +0 -50
  87. package/modules/calls/ui/messages.ts +0 -81
  88. package/modules/calls/ui/parts.tsx +0 -36
  89. package/modules/calls/ui/plugin.tsx +0 -15
  90. package/modules/sms/dist/client.css +0 -3
  91. package/modules/sms/dist/client.js +0 -1
  92. package/modules/sms/engenty.plugin.json +0 -8
  93. package/modules/sms/migrations/0001_init.sql +0 -26
  94. package/modules/sms/package.json +0 -24
  95. package/modules/sms/src/plugin.ts +0 -329
  96. package/modules/sms/src/schema.ts +0 -26
  97. package/modules/sms/src/store.ts +0 -140
  98. package/modules/sms/src/surface.ts +0 -70
  99. package/modules/sms/src/twilio.ts +0 -130
  100. package/modules/sms/tsconfig.json +0 -10
  101. package/modules/sms/ui/Settings.tsx +0 -113
  102. package/modules/sms/ui/Share.tsx +0 -60
  103. package/modules/sms/ui/app.ts +0 -51
  104. package/modules/sms/ui/messages.ts +0 -70
  105. package/modules/sms/ui/parts.tsx +0 -36
  106. package/modules/sms/ui/plugin.tsx +0 -20
  107. package/modules/whatsapp/dist/client.css +0 -3
  108. package/modules/whatsapp/dist/client.js +0 -1
  109. package/modules/whatsapp/engenty.plugin.json +0 -8
  110. package/modules/whatsapp/migrations/0001_init.sql +0 -30
  111. package/modules/whatsapp/package.json +0 -24
  112. package/modules/whatsapp/src/graph.ts +0 -271
  113. package/modules/whatsapp/src/inbound.ts +0 -143
  114. package/modules/whatsapp/src/plugin.ts +0 -374
  115. package/modules/whatsapp/src/schema.ts +0 -32
  116. package/modules/whatsapp/src/store.ts +0 -156
  117. package/modules/whatsapp/src/surface.ts +0 -127
  118. package/modules/whatsapp/tsconfig.json +0 -10
  119. package/modules/whatsapp/ui/Settings.tsx +0 -141
  120. package/modules/whatsapp/ui/Share.tsx +0 -60
  121. package/modules/whatsapp/ui/app.ts +0 -54
  122. package/modules/whatsapp/ui/messages.ts +0 -80
  123. package/modules/whatsapp/ui/parts.tsx +0 -36
  124. package/modules/whatsapp/ui/plugin.tsx +0 -20
@@ -1,137 +0,0 @@
1
- import { Button, Card, Input, Label, Select, Spinner } from "@engenty-wizards/web/ui";
2
- import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
3
- import { useEffect, useState } from "react";
4
- import { type AccountView, api, errorText, KEY, t } from "./app";
5
- import { Shown } from "./parts";
6
-
7
- /** Settings → Calls: Twilio, the OpenAI project, and what to enter where. */
8
- export function SettingsSection() {
9
- const cache = useQueryClient();
10
- const account = useQuery({
11
- queryKey: [KEY, "account"],
12
- queryFn: () => api().get<AccountView>("/account"),
13
- });
14
- const [form, setForm] = useState({
15
- twilioSid: "",
16
- twilioToken: "",
17
- smsFrom: "",
18
- openaiProject: "",
19
- openaiWebhookSecret: "",
20
- region: "eu" as "eu" | "us",
21
- });
22
- useEffect(() => {
23
- if (account.data) {
24
- setForm((f) => ({
25
- ...f,
26
- twilioSid: account.data.twilioSid,
27
- smsFrom: account.data.smsFrom,
28
- openaiProject: account.data.openaiProject,
29
- region: account.data.region,
30
- }));
31
- }
32
- }, [account.data]);
33
- const refresh = () => cache.invalidateQueries({ queryKey: [KEY] });
34
- const save = useMutation({
35
- mutationFn: () =>
36
- api().put<AccountView>("/account", {
37
- twilioSid: form.twilioSid,
38
- twilioToken: form.twilioToken || undefined,
39
- smsFrom: form.smsFrom || null,
40
- openaiProject: form.openaiProject,
41
- openaiWebhookSecret: form.openaiWebhookSecret || undefined,
42
- region: form.region,
43
- }),
44
- onSuccess: async () => {
45
- setForm((f) => ({ ...f, twilioToken: "", openaiWebhookSecret: "" }));
46
- await refresh();
47
- },
48
- });
49
- const remove = useMutation({
50
- mutationFn: () => api().del<AccountView>("/account"),
51
- onSuccess: refresh,
52
- });
53
- const set = (key: keyof typeof form) => (e: React.ChangeEvent<HTMLInputElement>) =>
54
- setForm((f) => ({ ...f, [key]: e.target.value }));
55
- const data = account.data;
56
- return (
57
- <section className="flex flex-col gap-2.5">
58
- <h2 className="px-1 font-display font-semibold text-lg leading-tight">{t("title")}</h2>
59
- <Card className="flex flex-col gap-4 p-5 text-[0.875rem]">
60
- <p className="text-[0.8125rem] text-ink-3">{t("intro")}</p>
61
- {account.isLoading ? <Spinner className="mx-auto" /> : null}
62
- <div>
63
- <Label hint={t("twilioSidHint")}>{t("twilioSid")}</Label>
64
- <Input value={form.twilioSid} onChange={set("twilioSid")} autoComplete="off" />
65
- </div>
66
- <div>
67
- <Label hint={data?.hasToken ? t("kept") : t("twilioTokenHint")}>{t("twilioToken")}</Label>
68
- <Input
69
- type="password"
70
- value={form.twilioToken}
71
- onChange={set("twilioToken")}
72
- placeholder={data?.hasToken ? "••••••••" : ""}
73
- autoComplete="new-password"
74
- />
75
- </div>
76
- <div>
77
- <Label hint={t("smsFromHint")}>{t("smsFrom")}</Label>
78
- <Input value={form.smsFrom} onChange={set("smsFrom")} inputMode="tel" />
79
- </div>
80
- <div>
81
- <Label hint={t("openaiProjectHint")}>{t("openaiProject")}</Label>
82
- <Input value={form.openaiProject} onChange={set("openaiProject")} autoComplete="off" />
83
- </div>
84
- <div>
85
- <Label hint={data?.hasSecret ? t("kept") : t("openaiSecretHint")}>
86
- {t("openaiSecret")}
87
- </Label>
88
- <Input
89
- type="password"
90
- value={form.openaiWebhookSecret}
91
- onChange={set("openaiWebhookSecret")}
92
- placeholder={data?.hasSecret ? "••••••••" : ""}
93
- autoComplete="new-password"
94
- />
95
- </div>
96
- <div>
97
- <Label>{t("region")}</Label>
98
- <Select
99
- className="w-40"
100
- value={form.region}
101
- onChange={(region) => setForm((f) => ({ ...f, region: region as "eu" | "us" }))}
102
- options={[
103
- { value: "eu", label: t("regionEu") },
104
- { value: "us", label: t("regionUs") },
105
- ]}
106
- />
107
- </div>
108
- <div className="flex items-center gap-3">
109
- <Button onClick={() => save.mutate()} busy={save.isPending}>
110
- {t("save")}
111
- </Button>
112
- {data?.connected ? (
113
- <Button variant="ghost" onClick={() => remove.mutate()} busy={remove.isPending}>
114
- {t("disconnect")}
115
- </Button>
116
- ) : null}
117
- {save.isSuccess ? (
118
- <span className="text-[0.8125rem] text-ink-3">{t("saved")}</span>
119
- ) : null}
120
- </div>
121
- {save.error ? <p className="text-[0.8125rem] text-rose">{errorText(save.error)}</p> : null}
122
- </Card>
123
- {data?.connected ? (
124
- <Card className="flex flex-col gap-4 p-5 text-[0.875rem]">
125
- <div className="font-medium">{t("setup")}</div>
126
- <Shown label={t("voiceWebhook")} value={data.voiceWebhook} />
127
- <p className="-mt-2 text-[0.8125rem] text-ink-3">{t("voiceWebhookHint")}</p>
128
- <Shown label={t("openaiWebhook")} value={data.openaiWebhook} />
129
- <p className="-mt-2 text-[0.8125rem] text-ink-3">{t("openaiWebhookHint")}</p>
130
- {data.sipUri ? <Shown label={t("sipUri")} value={data.sipUri} /> : null}
131
- <div className="font-medium">{t("meta")}</div>
132
- <p className="-mt-2 text-[0.8125rem] text-ink-3">{t("metaHint")}</p>
133
- </Card>
134
- ) : null}
135
- </section>
136
- );
137
- }
@@ -1,50 +0,0 @@
1
- import type { StudioPluginContext } from "@engenty-wizards/plugin-sdk/studio";
2
- import { messages } from "./messages";
3
-
4
- /** The studio this half was handed, and its words. */
5
-
6
- let current: StudioPluginContext | null = null;
7
- let translate: ((key: string, vars?: Record<string, string | number>) => string) | null = null;
8
-
9
- export function setStudio(studio: StudioPluginContext) {
10
- current = studio;
11
- translate = studio.i18n.register(messages) as typeof translate;
12
- }
13
-
14
- export function studio(): StudioPluginContext {
15
- if (!current) {
16
- throw new Error("The calls plugin is not loaded.");
17
- }
18
- return current;
19
- }
20
-
21
- export type Key = keyof (typeof messages)["de"];
22
- export const t = (key: Key, vars?: Record<string, string | number>) =>
23
- translate?.(key, vars) ?? key;
24
- export const api = () => studio().api;
25
-
26
- export const KEY = "calls";
27
-
28
- /** What a failed request says, in the person's language. */
29
- export function errorText(error: unknown): string {
30
- const body = (error as { body?: { code?: string; error?: string } } | null)?.body;
31
- const code = body?.code;
32
- const message = body?.error ?? (error instanceof Error ? error.message : String(error));
33
- if (code && `error_${code}` in messages.de) {
34
- return t(`error_${code}` as Key, { message });
35
- }
36
- return t("error_other", { message });
37
- }
38
-
39
- export interface AccountView {
40
- connected: boolean;
41
- twilioSid: string;
42
- hasToken: boolean;
43
- smsFrom: string;
44
- openaiProject: string;
45
- hasSecret: boolean;
46
- region: "eu" | "us";
47
- voiceWebhook: string;
48
- openaiWebhook: string;
49
- sipUri: string | null;
50
- }
@@ -1,81 +0,0 @@
1
- /** The studio half's words. `de` is the source. */
2
- export const messages = {
3
- de: {
4
- title: "Anrufe",
5
- intro:
6
- "Wizards laufen als Gespräch am Telefon: ein WhatsApp-Anruf auf die Business-Nummer oder ein Anruf auf eine Twilio-Nummer. Twilio trägt den Anruf, das Sprachmodell des OpenAI-Kontos (Einstellungen → Modelle) spricht; was eine Stimme nicht kann, kommt als Link per SMS.",
7
- twilioSid: "Twilio Account SID",
8
- twilioSidHint: "Aus der Twilio-Konsole, beginnt mit AC.",
9
- twilioToken: "Twilio Auth Token",
10
- twilioTokenHint: "Prüft auch jede Anfrage von Twilio auf ihre Signatur.",
11
- kept: "Ist hinterlegt. Leer lassen, um ihn zu behalten.",
12
- smsFrom: "SMS-Nummer",
13
- smsFromHint:
14
- "Eine SMS-fähige Twilio-Nummer, von der die Links kommen, mit Ländervorwahl. Ohne sie gibt es keine Links.",
15
- openaiProject: "OpenAI Project ID",
16
- openaiProjectHint: "Das Projekt, dessen API Key unter Modelle hinterlegt ist: proj_…",
17
- openaiSecret: "OpenAI Webhook Secret",
18
- openaiSecretHint:
19
- "Aus dem Webhook im OpenAI-Dashboard für das Ereignis realtime.call.incoming: whsec_…",
20
- region: "Region",
21
- regionEu: "EU",
22
- regionUs: "USA",
23
- save: "Speichern",
24
- saved: "Gespeichert.",
25
- disconnect: "Trennen",
26
- setup: "Eintragen",
27
- copy: "Kopieren",
28
- copied: "Kopiert",
29
- voiceWebhook: "Twilio: Voice-Webhook",
30
- voiceWebhookHint:
31
- "Bei der SIP-Domain (WhatsApp) und bei der Telefonnummer unter „A call comes in“, als Webhook mit HTTP POST.",
32
- openaiWebhook: "OpenAI: Webhook",
33
- openaiWebhookHint: "Im OpenAI-Dashboard als Webhook für realtime.call.incoming.",
34
- sipUri: "Wohin Twilio den Anruf gibt",
35
- meta: "Meta: SIP auf der WhatsApp-Nummer",
36
- metaHint:
37
- "In den Calling-Einstellungen der WhatsApp-Nummer: SIP einschalten, als Server die Twilio-SIP-Domain (…sip.twilio.com) mit Port 5061. Die SIP-Domain in Twilio erlaubt Metas Adressen in ihrer Zugriffsliste.",
38
- error_no_token: "Es braucht den Twilio Auth Token.",
39
- error_no_secret: "Es braucht das OpenAI Webhook Secret.",
40
- error_other: "{message}",
41
- },
42
- en: {
43
- title: "Calls",
44
- intro:
45
- "Wizards run as a conversation on the phone: a WhatsApp call to the business number or a call to a Twilio number. Twilio carries the call, the speech model of the OpenAI account (Settings → Models) speaks; what a voice cannot do arrives as a link by text.",
46
- twilioSid: "Twilio Account SID",
47
- twilioSidHint: "From the Twilio console, starts with AC.",
48
- twilioToken: "Twilio auth token",
49
- twilioTokenHint: "Also checks every request from Twilio for its signature.",
50
- kept: "Is set. Leave empty to keep it.",
51
- smsFrom: "Texting number",
52
- smsFromHint:
53
- "A Twilio number that can text, the links come from it, with the country code. Without it there are no links.",
54
- openaiProject: "OpenAI project ID",
55
- openaiProjectHint: "The project whose API key is set under Models: proj_…",
56
- openaiSecret: "OpenAI webhook secret",
57
- openaiSecretHint:
58
- "From the webhook in the OpenAI dashboard for the event realtime.call.incoming: whsec_…",
59
- region: "Region",
60
- regionEu: "EU",
61
- regionUs: "US",
62
- save: "Save",
63
- saved: "Saved.",
64
- disconnect: "Disconnect",
65
- setup: "Enter",
66
- copy: "Copy",
67
- copied: "Copied",
68
- voiceWebhook: "Twilio: voice webhook",
69
- voiceWebhookHint:
70
- "On the SIP domain (WhatsApp) and on the phone number under “A call comes in”, as a webhook with HTTP POST.",
71
- openaiWebhook: "OpenAI: webhook",
72
- openaiWebhookHint: "In the OpenAI dashboard as the webhook for realtime.call.incoming.",
73
- sipUri: "Where Twilio hands the call",
74
- meta: "Meta: SIP on the WhatsApp number",
75
- metaHint:
76
- "In the WhatsApp number's calling settings: switch SIP on, with the Twilio SIP domain (…sip.twilio.com) as the server on port 5061. The SIP domain in Twilio allows Meta's addresses in its access list.",
77
- error_no_token: "Twilio's auth token is needed.",
78
- error_no_secret: "OpenAI's webhook secret is needed.",
79
- error_other: "{message}",
80
- },
81
- } as const;
@@ -1,36 +0,0 @@
1
- import { IconButton } from "@engenty-wizards/web/ui";
2
- import { Check, Copy } from "lucide-react";
3
- import { useState } from "react";
4
- import { t } from "./app";
5
-
6
- /** A value to take along: the webhook address, the verify token, the link. */
7
- export function CopyButton({ text }: { text: string }) {
8
- const [done, setDone] = useState(false);
9
- return (
10
- <IconButton
11
- label={t(done ? "copied" : "copy")}
12
- className="size-8"
13
- onClick={() => {
14
- void navigator.clipboard.writeText(text).then(() => {
15
- setDone(true);
16
- setTimeout(() => setDone(false), 1500);
17
- });
18
- }}
19
- >
20
- {done ? <Check className="size-4" /> : <Copy className="size-4" />}
21
- </IconButton>
22
- );
23
- }
24
-
25
- /** A value shown as it is, with the button that copies it. */
26
- export function Shown({ label, value }: { label: string; value: string }) {
27
- return (
28
- <div className="flex items-center gap-2">
29
- <div className="min-w-0 flex-1">
30
- <div className="text-[0.8125rem] text-ink-3">{label}</div>
31
- <div className="select-all truncate font-mono text-[0.8125rem]">{value}</div>
32
- </div>
33
- <CopyButton text={value} />
34
- </div>
35
- );
36
- }
@@ -1,15 +0,0 @@
1
- import { defineStudioPlugin } from "@engenty-wizards/plugin-sdk/studio";
2
- import { PhoneCall } from "lucide-react";
3
- import { setStudio, t } from "./app";
4
- import { SettingsSection } from "./Settings";
5
-
6
- /** The studio half: Twilio, the OpenAI project and the addresses to enter, in the settings. */
7
- export default defineStudioPlugin((studio) => {
8
- setStudio(studio);
9
- studio.registerSettingsSection({
10
- id: "calls",
11
- label: () => t("title"),
12
- icon: PhoneCall,
13
- component: SettingsSection,
14
- });
15
- });
@@ -1,3 +0,0 @@
1
- /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-content:"";--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer wizards-plugin{[data-plugin=sms] .pointer-events-none{pointer-events:none}[data-plugin=sms] .absolute{position:absolute}[data-plugin=sms] .fixed{position:fixed}[data-plugin=sms] .relative{position:relative}[data-plugin=sms] .-top-1\.5{top:-.375rem}[data-plugin=sms] .top-0\.5{top:.125rem}[data-plugin=sms] .top-1\/2{top:50%}[data-plugin=sms] .-right-1\.5{right:-.375rem}[data-plugin=sms] .right-2{right:.5rem}[data-plugin=sms] .right-3{right:.75rem}[data-plugin=sms] .bottom-0\.5{bottom:.125rem}[data-plugin=sms] .bottom-1{bottom:.25rem}[data-plugin=sms] .left-0{left:0}[data-plugin=sms] .left-1\/2{left:50%}[data-plugin=sms] .z-50{z-index:50}[data-plugin=sms] .m-auto{margin:auto}[data-plugin=sms] .-mx-1{margin-inline:-.25rem}[data-plugin=sms] .mx-auto{margin-inline:auto}[data-plugin=sms] .my-1\.5{margin-block:.375rem}[data-plugin=sms] .-mt-1\.5{margin-top:-.375rem}[data-plugin=sms] .mt-0\.5{margin-top:.125rem}[data-plugin=sms] .mt-2{margin-top:.5rem}[data-plugin=sms] .-mr-2{margin-right:-.5rem}[data-plugin=sms] .mr-0\.5{margin-right:.125rem}[data-plugin=sms] .mb-2{margin-bottom:.5rem}[data-plugin=sms] .mb-5{margin-bottom:1.25rem}[data-plugin=sms] .-ml-1\.5{margin-left:-.375rem}[data-plugin=sms] .ml-1{margin-left:.25rem}[data-plugin=sms] .flex{display:flex}[data-plugin=sms] .grid{display:grid}[data-plugin=sms] .hidden{display:none}[data-plugin=sms] .inline-block{display:inline-block}[data-plugin=sms] .inline-flex{display:inline-flex}[data-plugin=sms] .size-1{width:.25rem;height:.25rem}[data-plugin=sms] .size-1\.5{width:.375rem;height:.375rem}[data-plugin=sms] .size-3{width:.75rem;height:.75rem}[data-plugin=sms] .size-3\.5{width:.875rem;height:.875rem}[data-plugin=sms] .size-4{width:1rem;height:1rem}[data-plugin=sms] .size-5{width:1.25rem;height:1.25rem}[data-plugin=sms] .size-6{width:1.5rem;height:1.5rem}[data-plugin=sms] .size-7{width:1.75rem;height:1.75rem}[data-plugin=sms] .size-8{width:2rem;height:2rem}[data-plugin=sms] .size-9{width:2.25rem;height:2.25rem}[data-plugin=sms] .size-11{width:2.75rem;height:2.75rem}[data-plugin=sms] .size-16{width:4rem;height:4rem}[data-plugin=sms] .h-6{height:1.5rem}[data-plugin=sms] .h-8{height:2rem}[data-plugin=sms] .h-9{height:2.25rem}[data-plugin=sms] .h-10{height:2.5rem}[data-plugin=sms] .h-11{height:2.75rem}[data-plugin=sms] .h-12{height:3rem}[data-plugin=sms] .h-px{height:1px}[data-plugin=sms] .max-h-56{max-height:14rem}[data-plugin=sms] .max-h-\[200px\]{max-height:200px}[data-plugin=sms] .max-h-\[calc\(100dvh-32px\)\]{max-height:calc(100dvh - 32px)}[data-plugin=sms] .min-h-9{min-height:2.25rem}[data-plugin=sms] .w-5{width:1.25rem}[data-plugin=sms] .w-11{width:2.75rem}[data-plugin=sms] .w-14{width:3.5rem}[data-plugin=sms] .w-72{width:18rem}[data-plugin=sms] .w-\[19rem\]{width:19rem}[data-plugin=sms] .w-\[calc\(100\%-32px\)\]{width:calc(100% - 32px)}[data-plugin=sms] .w-\[calc\(100\%-48px\)\]{width:calc(100% - 48px)}[data-plugin=sms] .w-full{width:100%}[data-plugin=sms] .w-px{width:1px}[data-plugin=sms] .max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}[data-plugin=sms] .max-w-\[calc\(100vw-16px\)\]{max-width:calc(100vw - 16px)}[data-plugin=sms] .max-w-full{max-width:100%}[data-plugin=sms] .max-w-xs{max-width:20rem}[data-plugin=sms] .min-w-0{min-width:0}[data-plugin=sms] .flex-1{flex:1}[data-plugin=sms] .shrink-0{flex-shrink:0}[data-plugin=sms] .-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=sms] .translate-x-\[2px\]{--tw-translate-x:2px;translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=sms] .translate-x-\[22px\]{--tw-translate-x:22px;translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=sms] .-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}[data-plugin=sms] .rotate-180{rotate:180deg}[data-plugin=sms] .transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}[data-plugin=sms] .animate-spin{animation:1s linear infinite spin}[data-plugin=sms] .cursor-pointer{cursor:pointer}[data-plugin=sms] .touch-none{touch-action:none}[data-plugin=sms] .resize{resize:both}[data-plugin=sms] .resize-none{resize:none}[data-plugin=sms] .\[scrollbar-width\:none\]{scrollbar-width:none}[data-plugin=sms] .appearance-none{appearance:none}[data-plugin=sms] .grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}[data-plugin=sms] .flex-col{flex-direction:column}[data-plugin=sms] .flex-wrap{flex-wrap:wrap}[data-plugin=sms] .place-items-center{place-items:center}[data-plugin=sms] .items-center{align-items:center}[data-plugin=sms] .items-end{align-items:flex-end}[data-plugin=sms] .items-start{align-items:flex-start}[data-plugin=sms] .justify-between{justify-content:space-between}[data-plugin=sms] .justify-center{justify-content:center}[data-plugin=sms] .gap-0\.5{gap:.125rem}[data-plugin=sms] .gap-1{gap:.25rem}[data-plugin=sms] .gap-1\.5{gap:.375rem}[data-plugin=sms] .gap-2{gap:.5rem}[data-plugin=sms] .gap-2\.5{gap:.625rem}[data-plugin=sms] .gap-3{gap:.75rem}[data-plugin=sms] .gap-4{gap:1rem}[data-plugin=sms] .gap-y-0\.5{row-gap:.125rem}[data-plugin=sms] .self-stretch{align-self:stretch}[data-plugin=sms] .truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-plugin=sms] .overflow-visible{overflow:visible}[data-plugin=sms] .overflow-x-auto{overflow-x:auto}[data-plugin=sms] .overflow-y-auto{overflow-y:auto}[data-plugin=sms] .overscroll-contain{overscroll-behavior:contain}[data-plugin=sms] .rounded-2xl{border-radius:calc(var(--radius) * 2)}[data-plugin=sms] .rounded-\[1\.375rem\]{border-radius:1.375rem}[data-plugin=sms] .rounded-full{border-radius:2147483647px}[data-plugin=sms] .rounded-lg{border-radius:var(--radius)}[data-plugin=sms] .rounded-md{border-radius:calc(var(--radius) * .75)}[data-plugin=sms] .rounded-xl{border-radius:calc(var(--radius) * 1.5)}[data-plugin=sms] .border{border-style:var(--tw-border-style);border-width:1px}[data-plugin=sms] .border-t{border-top-style:var(--tw-border-style);border-top-width:1px}[data-plugin=sms] .border-border{border-color:var(--border)}[data-plugin=sms] .border-border-soft{border-color:var(--border-soft)}[data-plugin=sms] .border-ember{border-color:var(--ember-mark)}[data-plugin=sms] .border-focus{border-color:var(--focus-line)}[data-plugin=sms] .border-input{border-color:var(--input)}[data-plugin=sms] .bg-amber-tint{background-color:var(--amber-tint)}[data-plugin=sms] .bg-border-soft{background-color:var(--border-soft)}[data-plugin=sms] .bg-card{background-color:var(--card)}[data-plugin=sms] .bg-ember{background-color:var(--ember-mark)}[data-plugin=sms] .bg-ember-tint{background-color:var(--ember-tint)}[data-plugin=sms] .bg-ink{background-color:var(--ink)}[data-plugin=sms] .bg-moss{background-color:var(--moss)}[data-plugin=sms] .bg-moss-tint{background-color:var(--moss-tint)}[data-plugin=sms] .bg-paper-2{background-color:var(--paper-2)}[data-plugin=sms] .bg-paper-3{background-color:var(--paper-3)}[data-plugin=sms] .bg-primary{background-color:var(--primary)}[data-plugin=sms] .bg-rose-tint{background-color:var(--rose-tint)}[data-plugin=sms] .bg-transparent{background-color:#0000}[data-plugin=sms] .bg-white{background-color:#fff}[data-plugin=sms] .bg-linear-to-l{--tw-gradient-position:to left}@supports (background-image:linear-gradient(in lab, red, red)){[data-plugin=sms] .bg-linear-to-l{--tw-gradient-position:to left in oklab}}[data-plugin=sms] .bg-linear-to-l{background-image:linear-gradient(var(--tw-gradient-stops))}[data-plugin=sms] .bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){[data-plugin=sms] .bg-linear-to-r{--tw-gradient-position:to right in oklab}}[data-plugin=sms] .bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}[data-plugin=sms] .from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}[data-plugin=sms] .from-50\%{--tw-gradient-from-position:50%}[data-plugin=sms] .to-ember-tint{--tw-gradient-to:var(--ember-tint);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}[data-plugin=sms] .to-50\%{--tw-gradient-to-position:50%}[data-plugin=sms] .fill-current{fill:currentColor}[data-plugin=sms] .object-cover{object-fit:cover}[data-plugin=sms] .p-0{padding:0}[data-plugin=sms] .p-0\.5{padding:.125rem}[data-plugin=sms] .p-1{padding:.25rem}[data-plugin=sms] .p-1\.5{padding:.375rem}[data-plugin=sms] .p-3{padding:.75rem}[data-plugin=sms] .p-5{padding:1.25rem}[data-plugin=sms] .px-1{padding-inline:.25rem}[data-plugin=sms] .px-2{padding-inline:.5rem}[data-plugin=sms] .px-2\.5{padding-inline:.625rem}[data-plugin=sms] .px-3{padding-inline:.75rem}[data-plugin=sms] .px-3\.5{padding-inline:.875rem}[data-plugin=sms] .px-4{padding-inline:1rem}[data-plugin=sms] .px-6{padding-inline:1.5rem}[data-plugin=sms] .py-1{padding-block:.25rem}[data-plugin=sms] .py-1\.5{padding-block:.375rem}[data-plugin=sms] .py-2{padding-block:.5rem}[data-plugin=sms] .py-2\.5{padding-block:.625rem}[data-plugin=sms] .py-16{padding-block:4rem}[data-plugin=sms] .pt-1\.5{padding-top:.375rem}[data-plugin=sms] .pt-2{padding-top:.5rem}[data-plugin=sms] .pr-1{padding-right:.25rem}[data-plugin=sms] .pr-9{padding-right:2.25rem}[data-plugin=sms] .pb-1{padding-bottom:.25rem}[data-plugin=sms] .pl-2{padding-left:.5rem}[data-plugin=sms] .pl-2\.5{padding-left:.625rem}[data-plugin=sms] .text-center{text-align:center}[data-plugin=sms] .text-left{text-align:left}[data-plugin=sms] .font-display{font-family:var(--f-display)}[data-plugin=sms] .font-mono{font-family:var(--f-mono)}[data-plugin=sms] .text-lg{font-size:1.125rem;line-height:var(--tw-leading,calc(1.75 / 1.125))}[data-plugin=sms] .text-sm{font-size:.875rem;line-height:var(--tw-leading,calc(1.25 / .875))}[data-plugin=sms] .text-xl{font-size:1.25rem;line-height:var(--tw-leading,calc(1.75 / 1.25))}[data-plugin=sms] .text-\[0\.75rem\]{font-size:.75rem}[data-plugin=sms] .text-\[0\.875rem\]{font-size:.875rem}[data-plugin=sms] .text-\[0\.6875rem\]{font-size:.6875rem}[data-plugin=sms] .text-\[0\.8125rem\]{font-size:.8125rem}[data-plugin=sms] .text-\[0\.9375rem\]{font-size:.9375rem}[data-plugin=sms] .text-\[14px\]{font-size:14px}[data-plugin=sms] .leading-5{--tw-leading:calc(.25rem * 5);line-height:1.25rem}[data-plugin=sms] .leading-\[1\.5\]{--tw-leading:1.5;line-height:1.5}[data-plugin=sms] .leading-tight{--tw-leading:1.25;line-height:1.25}[data-plugin=sms] .font-medium{--tw-font-weight:500;font-weight:500}[data-plugin=sms] .font-semibold{--tw-font-weight:600;font-weight:600}[data-plugin=sms] .tracking-wide{--tw-tracking:.025em;letter-spacing:.025em}[data-plugin=sms] .whitespace-nowrap{white-space:nowrap}[data-plugin=sms] .text-ember{color:var(--ember-mark)}[data-plugin=sms] .text-ember-strong{color:var(--ember-strong-mark)}[data-plugin=sms] .text-ink{color:var(--ink)}[data-plugin=sms] .text-ink-2{color:var(--ink-2)}[data-plugin=sms] .text-ink-3{color:var(--ink-3)}[data-plugin=sms] .text-ink-4{color:var(--ink-4)}[data-plugin=sms] .text-moss{color:var(--moss)}[data-plugin=sms] .text-paper{color:var(--paper)}[data-plugin=sms] .text-primary-foreground{color:var(--primary-foreground)}[data-plugin=sms] .text-rose{color:var(--rose)}[data-plugin=sms] .capitalize{text-transform:capitalize}[data-plugin=sms] .uppercase{text-transform:uppercase}[data-plugin=sms] .tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}[data-plugin=sms] .line-through{text-decoration-line:line-through}[data-plugin=sms] .underline{text-decoration-line:underline}[data-plugin=sms] .underline-offset-2{text-underline-offset:2px}[data-plugin=sms] .opacity-0{opacity:0}[data-plugin=sms] .opacity-35{opacity:.35}[data-plugin=sms] .shadow-\[0_1px_0_oklch\(0\%_0_0\/0\.08\)\]{--tw-shadow:0 1px 0 var(--tw-shadow-color,oklch(0% 0 0/.08));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .shadow-\[inset_0_1px_0_oklch\(0\%_0_0\/0\.02\)\]{--tw-shadow:inset 0 1px 0 var(--tw-shadow-color,oklch(0% 0 0/.02));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .shadow-overlay{--tw-shadow:var(--shadow-ember-overlay);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .shadow-soft{--tw-shadow:var(--shadow-ember-soft);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .ring-4{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .ring-border{--tw-ring-color:var(--border)}[data-plugin=sms] .ring-border-soft{--tw-ring-color:var(--border-soft)}[data-plugin=sms] .ring-focus-glow{--tw-ring-color:var(--focus-glow)}[data-plugin=sms] .transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=sms] .transition-\[background\,filter\,color\,transform\]{transition-property:background,filter,color,transform;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=sms] .transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=sms] .transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,cubic-bezier(.4, 0, .2, 1));transition-duration:var(--tw-duration,.15s)}[data-plugin=sms] .duration-150{--tw-duration:.15s;transition-duration:.15s}[data-plugin=sms] .duration-200{--tw-duration:.2s;transition-duration:.2s}[data-plugin=sms] .ease-out{--tw-ease:cubic-bezier(0, 0, .2, 1);transition-timing-function:cubic-bezier(0,0,.2,1)}[data-plugin=sms] .outline-none{--tw-outline-style:none;outline-style:none}[data-plugin=sms] .select-all{-webkit-user-select:all;user-select:all}[data-plugin=sms] .select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){[data-plugin=sms] .group-hover\:scale-110:is(:where(.group):hover *){--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)}[data-plugin=sms] .group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}[data-plugin=sms] .placeholder\:truncate::placeholder{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-plugin=sms] .placeholder\:text-ink-4::placeholder{color:var(--ink-4)}[data-plugin=sms] .backdrop\:bg-\[oklch\(20\%_0\.01_60\/0\.28\)\]::backdrop{background-color:oklch(20% .01 60/.28)}[data-plugin=sms] .backdrop\:backdrop-blur-\[2px\]::backdrop{--tw-backdrop-blur:blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}[data-plugin=sms] .before\:absolute:before{content:var(--tw-content);position:absolute}[data-plugin=sms] .before\:-inset-x-1:before{content:var(--tw-content);inset-inline:-.25rem}[data-plugin=sms] .before\:-inset-y-2\.5:before{content:var(--tw-content);inset-block:-.625rem}[data-plugin=sms] .before\:content-\[\'\'\]:before{--tw-content:"";content:var(--tw-content)}[data-plugin=sms] .focus-within\:ring-focus:focus-within{--tw-ring-color:var(--focus-line)}@media (hover:hover){[data-plugin=sms] .hover\:border-ink-4:hover{border-color:var(--ink-4)}[data-plugin=sms] .hover\:bg-accent:hover{background-color:var(--accent)}[data-plugin=sms] .hover\:bg-card:hover{background-color:var(--card)}[data-plugin=sms] .hover\:bg-paper-2:hover{background-color:var(--paper-2)}[data-plugin=sms] .hover\:bg-paper-3:hover{background-color:var(--paper-3)}[data-plugin=sms] .hover\:bg-rose-tint:hover{background-color:var(--rose-tint)}[data-plugin=sms] .hover\:text-ink:hover{color:var(--ink)}[data-plugin=sms] .hover\:text-ink-2:hover{color:var(--ink-2)}[data-plugin=sms] .hover\:text-rose:hover{color:var(--rose)}[data-plugin=sms] .hover\:brightness-\[1\.06\]:hover{--tw-brightness:brightness(1.06);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}}[data-plugin=sms] .focus\:border-focus:focus{border-color:var(--focus-line)}[data-plugin=sms] .focus\:ring-4:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .focus\:ring-focus-glow:focus{--tw-ring-color:var(--focus-glow)}[data-plugin=sms] .focus-visible\:border-focus:focus-visible{border-color:var(--focus-line)}[data-plugin=sms] .focus-visible\:opacity-100:focus-visible{opacity:1}[data-plugin=sms] .focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}[data-plugin=sms] .focus-visible\:ring-focus:focus-visible{--tw-ring-color:var(--focus-line)}[data-plugin=sms] .focus-visible\:ring-focus-glow:focus-visible{--tw-ring-color:var(--focus-glow)}[data-plugin=sms] .active\:scale-\[0\.98\]:active{scale:.98}[data-plugin=sms] .active\:brightness-95:active{--tw-brightness:brightness(95%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}[data-plugin=sms] .disabled\:pointer-events-none:disabled{pointer-events:none}[data-plugin=sms] .disabled\:line-through:disabled{text-decoration-line:line-through}[data-plugin=sms] .disabled\:opacity-40:disabled{opacity:.4}[data-plugin=sms] .disabled\:opacity-50:disabled{opacity:.5}[data-plugin=sms] .disabled\:opacity-60:disabled{opacity:.6}@media (prefers-reduced-motion:reduce){[data-plugin=sms] .motion-reduce\:transition-none{transition-property:none}}@media not all and (width>=48rem){[data-plugin=sms] .max-md\:hidden{display:none}}@media not all and (width>=40rem){[data-plugin=sms] .max-sm\:m-0{margin:0}[data-plugin=sms] .max-sm\:h-dvh{height:100dvh}[data-plugin=sms] .max-sm\:max-h-none{max-height:none}[data-plugin=sms] .max-sm\:w-full{width:100%}[data-plugin=sms] .max-sm\:max-w-none{max-width:none}[data-plugin=sms] .max-sm\:rounded-none{border-radius:0}[data-plugin=sms] .max-sm\:pt-\[env\(safe-area-inset-top\)\]{padding-top:env(safe-area-inset-top)}[data-plugin=sms] .max-sm\:pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}}@media (width>=40rem){[data-plugin=sms] .sm\:h-\[min\(calc\(100dvh-32px\)\,56rem\)\]{height:min(100dvh - 32px,56rem)}[data-plugin=sms] .sm\:max-w-2xl{max-width:42rem}[data-plugin=sms] .sm\:max-w-4xl{max-width:56rem}[data-plugin=sms] .sm\:max-w-md{max-width:28rem}[data-plugin=sms] .sm\:p-7{padding:1.75rem}}@media (width>=48rem){[data-plugin=sms] .md\:hidden{display:none}}@media (pointer:coarse){[data-plugin=sms] .coarse\:size-10{width:2.5rem;height:2.5rem}[data-plugin=sms] .coarse\:size-11{width:2.75rem;height:2.75rem}[data-plugin=sms] .coarse\:h-9{height:2.25rem}[data-plugin=sms] .coarse\:h-11{height:2.75rem}[data-plugin=sms] .coarse\:min-h-11{min-height:2.75rem}[data-plugin=sms] .coarse\:px-4{padding-inline:1rem}[data-plugin=sms] .coarse\:py-3{padding-block:.75rem}}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
3
- /*$vite$:1*/
@@ -1 +0,0 @@
1
- var __wizardsPlugin_sms=(function(e,t,n,r,i){var a=e=>e?.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase();function o(e,t,n=[]){if(t==null)throw Error(`[lucide]: iconNode is required when icon name is used`);return{name:a(e),size:24,node:t,...n.length>0?{aliases:n}:{}}}var s=e=>{let t=``,n=!1;for(let r of e){if(r===`-`||r===`_`||r<=` `){n=t.length>0;continue}t.length===0?t+=r.toLowerCase():t+=n?r.toUpperCase():r,n=!1}return t},c=e=>{let t=s(e);return t.charAt(0).toUpperCase()+t.slice(1)},l=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),u={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`};function d(e){return e!=null}function f(e,t={}){let n=t.attributeNames??{},r=e=>n[e]??e,i=e.size??e.width??u.width,a=e.size??e.height??u.height,o=e.aliases?.filter(e=>typeof e==`string`&&e.trim()!==``).map(e=>`lucide-${e}`)??[],s=[...e.name?[`lucide-${e.name}`]:[],...o],c=t.className?.split(` `).filter(Boolean)??[],f=t.includeDefaultClasses===!1?l(...c):l(`lucide`,...s,...c),p=t.absoluteStrokeWidth?Number(t.strokeWidth??u[`stroke-width`])*Number(e.size??e.width??u.width)/Number(t.size??t.width??u.width):t.strokeWidth??u[`stroke-width`];return[`svg`,{...Object.entries(u).reduce((e,[t,n])=>(e[r(t)]=n,e),{}),...`color`in t&&t.color&&{[r(`stroke`)]:t.color},...`size`in t&&d(t.size)&&{[r(`width`)]:t.size,[r(`height`)]:t.size},...`width`in t&&d(t.width)&&{[r(`width`)]:t.width},...`height`in t&&d(t.height)&&{[r(`height`)]:t.height},[r(`stroke-width`)]:p,...f&&{[r(`class`)]:f},[r(`viewBox`)]:`0 0 ${i} ${a}`,...t.hasA11yProp===!1?{[r(`aria-hidden`)]:`true`}:{},...`attributes`in t&&t.attributes},e.node.map(e=>{let[n,i,a]=e,o=t.nonScalingStroke?{[r(`vector-effect`)]:`non-scaling-stroke`,...i}:i;return a?[n,o,a]:[n,o]})]}function p(e,t={}){return f(e,{...t,attributeNames:{...t.attributeNames,class:`className`,"stroke-width":`strokeWidth`,"stroke-linecap":`strokeLinecap`,"stroke-linejoin":`strokeLinejoin`,"vector-effect":`vectorEffect`}})}var m=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},h=(0,t.createContext)({}),g=()=>(0,t.useContext)(h),_=(0,t.forwardRef)(({color:e,size:n,width:r,height:i,strokeWidth:a,absoluteStrokeWidth:o,nonScalingStroke:s,className:c=``,children:u,iconNode:d=[],icon:f={node:d,aliases:[],size:24},...h},_)=>{let{size:v=24,strokeWidth:y=2,absoluteStrokeWidth:b=!1,nonScalingStroke:x=!1,color:S=`currentColor`,className:C=``}=g()??{},w=!!u||m(h),[T,E,D=[]]=p(f,{color:e??S,width:r??n??v,height:i??n??v,strokeWidth:a??y,absoluteStrokeWidth:o??b,nonScalingStroke:s??x,className:l(C,c),hasA11yProp:w,attributes:h});return(0,t.createElement)(T,{ref:_,...E},[...D.map(([e,n])=>(0,t.createElement)(e,n)),...Array.isArray(u)?u:[u]])});function v(e,n=[],r=[]){let i=typeof e==`string`?o(e,n,r):e,a=(0,t.forwardRef)(({className:e,...n},r)=>(0,t.createElement)(_,{ref:r,icon:i,className:e,...n}));return i.name&&(a.displayName=c(i.name)),a}var y={name:`check`,size:24,node:[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]};y.node;var b=v(y),x={name:`copy`,size:24,node:[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]};x.node;var S=v(x),C={name:`message-square-text`,size:24,node:[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}],[`path`,{d:`M7 11h10`,key:`1twpyw`}],[`path`,{d:`M7 15h6`,key:`d9of3u`}],[`path`,{d:`M7 7h8`,key:`af5zfr`}]]};C.node;var w=v(C),T={de:{title:`SMS`,intro:`Wizards laufen per SMS auf der eigenen Nummer: eine Frage pro Nachricht, Auswahl als Nummern, Bilder und Dateien als Link. Dafür braucht es ein Twilio-Konto mit einer SMS-fähigen Nummer.`,accountSid:`Account SID`,accountSidHint:`Aus der Twilio-Konsole, beginnt mit AC.`,token:`Auth Token`,tokenHint:`Der Auth Token des Kontos. Damit wird auch jede Nachricht von Twilio auf ihre Signatur geprüft.`,tokenKept:`Ist hinterlegt. Leer lassen, um ihn zu behalten.`,number:`Nummer`,numberHint:`Die Twilio-Nummer, von der die Texte kommen, mit Ländervorwahl: +43660…`,save:`Speichern`,saved:`Gespeichert.`,disconnect:`Trennen`,twilio:`In Twilio eintragen`,twilioHint:`Bei der Nummer unter Messaging → „A message comes in“: diese Adresse, als Webhook mit HTTP POST.`,webhook:`Webhook-Adresse`,copy:`Kopieren`,copied:`Kopiert`,testTo:`Test-SMS an`,sendTest:`Senden`,testSent:`Angekommen? Dann passt alles.`,keyword:`Stichwort`,keywordHint:`Wer dieses Wort an die Nummer schreibt, startet den Wizard. Der Link und der QR-Code tippen es vor.`,error_bad_keyword:`Ein Stichwort besteht aus Buchstaben, Ziffern, Leerzeichen und Bindestrichen, bis zu 40.`,error_keyword_taken:`Ein anderer Wizard hat dieses Stichwort schon.`,error_no_token:`Es braucht einen Auth Token.`,error_provider:`Twilio hat die Nachricht nicht angenommen: {message}`,error_other:`{message}`},en:{title:`SMS`,intro:`Wizards run by text message on your own number: one question per text, choices as numbers, pictures and files as links. It takes a Twilio account with a number that can text.`,accountSid:`Account SID`,accountSidHint:`From the Twilio console, starts with AC.`,token:`Auth token`,tokenHint:`The account's auth token. It also checks every message from Twilio for its signature.`,tokenKept:`Is set. Leave empty to keep it.`,number:`Number`,numberHint:`The Twilio number the texts come from, with the country code: +43660…`,save:`Save`,saved:`Saved.`,disconnect:`Disconnect`,twilio:`Enter in Twilio`,twilioHint:`On the number under Messaging → “A message comes in”: this address, as a webhook with HTTP POST.`,webhook:`Webhook address`,copy:`Copy`,copied:`Copied`,testTo:`Test text to`,sendTest:`Send`,testSent:`Arrived? Then everything is set.`,keyword:`Keyword`,keywordHint:`Whoever texts this word to the number starts the wizard. The link and the QR code type it for them.`,error_bad_keyword:`A keyword is letters, digits, spaces and dashes, up to 40.`,error_keyword_taken:`Another wizard has this keyword already.`,error_no_token:`An auth token is needed.`,error_provider:`Twilio did not take the message: {message}`,error_other:`{message}`}},E=null,D=null;function O(e){E=e,D=e.i18n.register(T)}function k(){if(!E)throw Error(`The SMS plugin is not loaded.`);return E}var A=(e,t)=>D?.(e,t)??e,j=()=>k().api;function M(e){let t=e?.body,n=t?.code,r=t?.error??(e instanceof Error?e.message:String(e));return n&&`error_${n}`in T.de?A(`error_${n}`,{message:r}):A(`error_other`,{message:r})}function N({text:e}){let[r,a]=(0,t.useState)(!1);return(0,i.jsx)(n.IconButton,{label:A(r?`copied`:`copy`),className:`size-8`,onClick:()=>{navigator.clipboard.writeText(e).then(()=>{a(!0),setTimeout(()=>a(!1),1500)})},children:r?(0,i.jsx)(b,{className:`size-4`}):(0,i.jsx)(S,{className:`size-4`})})}function P({label:e,value:t}){return(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`div`,{className:`text-[0.8125rem] text-ink-3`,children:e}),(0,i.jsx)(`div`,{className:`select-all truncate font-mono text-[0.8125rem]`,children:t})]}),(0,i.jsx)(N,{text:t})]})}function F(){let e=(0,r.useQueryClient)(),a=(0,r.useQuery)({queryKey:[`sms`,`account`],queryFn:()=>j().get(`/account`)}),[o,s]=(0,t.useState)({accountSid:``,number:``,authToken:``}),[c,l]=(0,t.useState)(``);(0,t.useEffect)(()=>{a.data&&s(e=>({...e,accountSid:a.data.accountSid,number:a.data.number}))},[a.data]);let u=()=>e.invalidateQueries({queryKey:[`sms`]}),d=(0,r.useMutation)({mutationFn:()=>j().put(`/account`,{accountSid:o.accountSid,number:o.number,authToken:o.authToken||void 0}),onSuccess:async()=>{s(e=>({...e,authToken:``})),await u()}}),f=(0,r.useMutation)({mutationFn:()=>j().del(`/account`),onSuccess:u}),p=(0,r.useMutation)({mutationFn:()=>j().post(`/account/test`,{to:c})}),m=e=>t=>s(n=>({...n,[e]:t.target.value})),h=a.data;return(0,i.jsxs)(`section`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsx)(`h2`,{className:`px-1 font-display font-semibold text-lg leading-tight`,children:A(`title`)}),(0,i.jsxs)(n.Card,{className:`flex flex-col gap-4 p-5 text-[0.875rem]`,children:[(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-ink-3`,children:A(`intro`)}),a.isLoading?(0,i.jsx)(n.Spinner,{className:`mx-auto`}):null,(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:A(`accountSidHint`),children:A(`accountSid`)}),(0,i.jsx)(n.Input,{value:o.accountSid,onChange:m(`accountSid`),autoComplete:`off`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:h?.hasToken?A(`tokenKept`):A(`tokenHint`),children:A(`token`)}),(0,i.jsx)(n.Input,{type:`password`,value:o.authToken,onChange:m(`authToken`),placeholder:h?.hasToken?`••••••••`:``,autoComplete:`new-password`})]}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{hint:A(`numberHint`),children:A(`number`)}),(0,i.jsx)(n.Input,{value:o.number,onChange:m(`number`),inputMode:`tel`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(n.Button,{onClick:()=>d.mutate(),busy:d.isPending,children:A(`save`)}),h?.connected?(0,i.jsx)(n.Button,{variant:`ghost`,onClick:()=>f.mutate(),busy:f.isPending,children:A(`disconnect`)}):null,d.isSuccess?(0,i.jsx)(`span`,{className:`text-[0.8125rem] text-ink-3`,children:A(`saved`)}):null]}),d.error?(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:M(d.error)}):null]}),h?.connected?(0,i.jsxs)(n.Card,{className:`flex flex-col gap-4 p-5 text-[0.875rem]`,children:[(0,i.jsx)(`div`,{className:`font-medium`,children:A(`twilio`)}),(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-ink-3`,children:A(`twilioHint`)}),(0,i.jsx)(P,{label:A(`webhook`),value:h.webhook}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(n.Label,{children:A(`testTo`)}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(n.Input,{value:c,onChange:e=>l(e.target.value),placeholder:`+43 660 …`,inputMode:`tel`,className:`max-w-xs`}),(0,i.jsx)(n.Button,{variant:`secondary`,onClick:()=>p.mutate(),busy:p.isPending,children:A(`sendTest`)})]}),p.isSuccess?(0,i.jsx)(`p`,{className:`mt-2 text-[0.8125rem] text-ink-3`,children:A(`testSent`)}):null,p.error?(0,i.jsx)(`p`,{className:`mt-2 text-[0.8125rem] text-rose`,children:M(p.error)}):null]})]}):null]})}function I({wizard:e}){let a=(0,r.useQueryClient)(),o=(0,r.useQuery)({queryKey:[`sms`,`binding`,e.id],queryFn:()=>j().get(`/binding/${e.id}`)}),[s,c]=(0,t.useState)(null),l=(0,r.useMutation)({mutationFn:t=>j().put(`/binding/${e.id}`,{keyword:t}),onSuccess:async()=>{c(null),await Promise.all([a.invalidateQueries({queryKey:[`sms`,`binding`,e.id]}),a.invalidateQueries({queryKey:[`wizard-runners`,e.id]})])}});if(!o.data)return null;let u=s??o.data.keyword;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsxs)(`label`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsx)(`span`,{className:`font-medium text-[0.875rem]`,children:A(`keyword`)}),(0,i.jsx)(n.Input,{value:u,onChange:e=>c(e.target.value),onBlur:()=>{s?.trim()&&s.trim()!==o.data?.keyword?l.mutate(s):c(null)},onKeyDown:e=>{e.key===`Enter`&&e.currentTarget.blur()},className:`max-w-xs`})]}),(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-ink-3`,children:A(`keywordHint`)}),l.error?(0,i.jsx)(`p`,{className:`text-[0.8125rem] text-rose`,children:M(l.error)}):null]})}return(0,e.defineStudioPlugin)(e=>{O(e),e.registerSettingsSection({id:`sms`,label:()=>A(`title`),icon:w,component:F}),e.registerShareSection({runner:`sms`,component:I})})})(__WIZARDS_STUDIO__.sdk,__WIZARDS_STUDIO__.react,__WIZARDS_STUDIO__.ui,__WIZARDS_STUDIO__.query,__WIZARDS_STUDIO__.jsx);
@@ -1,8 +0,0 @@
1
- {
2
- "id": "sms",
3
- "name": "SMS",
4
- "version": "0.1.0",
5
- "description": "Runs wizards by text message: a keyword to the tenant's number starts one, the fields come one message at a time with numbered choices, and what the wizard makes arrives as text and links. Talks to Twilio with the tenant's own account and number; keeps the threads in the tenant's database. Text only: photos, files and signatures go to the wizard's page by link.",
6
- "kind": "module",
7
- "provides": ["runner.sms"]
8
- }
@@ -1,26 +0,0 @@
1
- -- The tenant's Twilio account and the number it texts from. One row. Dates are milliseconds.
2
- CREATE TABLE sms_account (
3
- id INTEGER PRIMARY KEY CHECK (id = 1),
4
- account_sid TEXT NOT NULL,
5
- auth_token TEXT NOT NULL,
6
- number TEXT NOT NULL,
7
- updated_at INTEGER NOT NULL
8
- );
9
-
10
- -- The keyword that starts a wizard on the number: sms:<number>?body=<keyword>.
11
- CREATE TABLE sms_binding (
12
- wizard_id TEXT PRIMARY KEY,
13
- keyword TEXT NOT NULL COLLATE NOCASE
14
- );
15
- CREATE UNIQUE INDEX sms_binding_keyword ON sms_binding (keyword);
16
-
17
- -- One thread per number that wrote: the run it is in, and where in it (state is JSON).
18
- CREATE TABLE sms_thread (
19
- number TEXT PRIMARY KEY,
20
- run_id TEXT,
21
- state TEXT NOT NULL,
22
- last_inbound_at INTEGER NOT NULL,
23
- last_message_id TEXT,
24
- updated_at INTEGER NOT NULL
25
- );
26
- CREATE INDEX sms_thread_run ON sms_thread (run_id);
@@ -1,24 +0,0 @@
1
- {
2
- "name": "@engenty-wizards/module-sms",
3
- "version": "0.1.0",
4
- "license": "FSL-1.1-MIT",
5
- "private": true,
6
- "type": "module",
7
- "scripts": {
8
- "build": "node ../../scripts/build-plugin.mjs .",
9
- "dev": "node ../../scripts/build-plugin.mjs . --watch",
10
- "typecheck": "tsc -p tsconfig.json --noEmit"
11
- },
12
- "devDependencies": {
13
- "@engenty-wizards/plugin-sdk": "workspace:*",
14
- "@engenty-wizards/web": "workspace:*",
15
- "@tanstack/react-query": "^5.104.0",
16
- "@types/node": "^26.6.4",
17
- "@types/react": "^19.3.0",
18
- "drizzle-orm": "^0.45.3",
19
- "lucide-react": "^1.49.0",
20
- "react": "19.3.0",
21
- "typescript": "~6.0.3",
22
- "zod": "4.6.5"
23
- }
24
- }