@agent-native/core 0.141.2 → 0.141.4
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +1 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +56 -18
- package/corpus/templates/analytics/changelog/2026-08-05-analytics-queries-keep-every-table-tenant-scoped.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-05-durable-a2a-workers-avoid-startup-migration-contention.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-05-fixed-sign-in-and-dashboard-requests-failing-when-background.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-05-historical-rollups-stay-complete-while-live-events-arrive.md +6 -0
- package/corpus/templates/analytics/server/db/schema.ts +1 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +2 -0
- package/corpus/templates/analytics/server/lib/emails.ts +51 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +8 -12
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +9 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +262 -13
- package/corpus/templates/analytics/server/lib/gong.ts +132 -33
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/analytics/server/plugins/auth.ts +21 -2
- package/corpus/templates/analytics/server/plugins/db.ts +35 -10
- package/corpus/templates/analytics/server/plugins/transactional-emails.ts +5 -0
- package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +17 -7
- package/corpus/templates/calendar/server/lib/booking-emails.ts +154 -70
- package/corpus/templates/calendar/server/lib/emails.ts +167 -0
- package/corpus/templates/calendar/server/lib/event-guest-notifications.ts +64 -28
- package/corpus/templates/calendar/server/plugins/transactional-emails.ts +5 -0
- package/corpus/templates/clips/actions/invite-member.ts +39 -16
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +73 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +10 -25
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -0
- package/corpus/templates/clips/changelog/2026-08-05-activity-is-now-the-default-clips-recording-tab-and-ai-setup.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-05-clips-can-copy-a-linked-email-preview-for-public-recordings.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-05-preparing-recording-now-uses-a-clean-shadow-free-status-card.md +6 -0
- package/corpus/templates/clips/desktop/src/styles.css +0 -3
- package/corpus/templates/clips/server/lib/emails.ts +256 -0
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +24 -0
- package/corpus/templates/clips/server/plugins/transactional-email-catalog.ts +5 -0
- package/corpus/templates/clips/server/routes/api/thumbnail/[recordingId].get.ts +4 -1
- package/corpus/templates/clips/shared/email-preview.ts +61 -0
- package/corpus/templates/content/server/lib/comment-notifications.ts +57 -26
- package/corpus/templates/content/server/lib/emails.ts +70 -0
- package/corpus/templates/content/server/plugins/transactional-emails.ts +5 -0
- package/corpus/templates/design/actions/import-design-tokens.ts +11 -8
- package/corpus/templates/design/actions/index-design-tokens.ts +13 -6
- package/corpus/templates/design/changelog/2026-08-05-design-token-imports-classify-typography-dimensions-correctly.md +6 -0
- package/corpus/templates/dispatch/app/routes/transactional-email.$appId.$id.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/transactional-email.tsx +4 -0
- package/corpus/templates/dispatch/changelog/2026-08-05-transactional-email-catalogs-and-delivery-activity-are-available-again.md +6 -0
- package/corpus/templates/factory/AGENTS.md +18 -17
- package/corpus/templates/factory/actions/get-factory-automation-health.ts +50 -0
- package/corpus/templates/factory/actions/get-triage-config.ts +8 -0
- package/corpus/templates/factory/actions/save-triage-config.ts +26 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +27 -0
- package/corpus/templates/factory/app/routes/factory.tsx +376 -206
- package/corpus/templates/factory/changelog/2026-08-05-factory-now-keeps-production-automations-running-shows-sched.md +6 -0
- package/corpus/templates/factory/server/db/schema.ts +6 -0
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +10 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +141 -2
- package/corpus/templates/forms/app/pages/FormsListPage.tsx +41 -21
- package/corpus/templates/forms/changelog/2026-08-05-form-links-can-now-be-cmd-clicked-to-open-in-a-new-tab.md +6 -0
- package/corpus/templates/forms/server/lib/emails.ts +52 -0
- package/corpus/templates/forms/server/lib/response-email.ts +2 -0
- package/corpus/templates/forms/server/plugins/transactional-emails.ts +5 -0
- package/corpus/templates/plan/actions/request-plan-access.ts +33 -12
- package/corpus/templates/plan/server/lib/comment-notifications.ts +53 -27
- package/corpus/templates/plan/server/lib/emails.ts +67 -0
- package/corpus/templates/plan/server/plugins/transactional-emails.ts +5 -0
- package/corpus/templates/slides/actions/import-from-url.ts +1 -0
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +492 -381
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +8 -7
- package/corpus/templates/slides/app/components/layout/Layout.tsx +27 -23
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +313 -0
- package/corpus/templates/slides/app/components/ui/command.tsx +1 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +8 -2
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +305 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +12 -12
- package/corpus/templates/slides/app/pages/Index.tsx +127 -137
- package/corpus/templates/slides/app/root.tsx +8 -0
- package/corpus/templates/slides/changelog/2026-08-05-deck-browsing-keeps-all-and-mine-in-the-header-with-a-tighte.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-new-deck-creation-now-flows-through-a-clean-full-screen-refe.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-website-imports-now-include-linked-stylesheets-for-more-accu.md +6 -0
- package/corpus/templates/slides/server/lib/comment-notifications.ts +44 -21
- package/corpus/templates/slides/server/lib/emails.ts +40 -0
- package/corpus/templates/slides/server/plugins/transactional-emails.ts +5 -0
- package/dist/brand-kit/index.d.ts +1 -0
- package/dist/brand-kit/index.js +1 -0
- package/dist/brand-kit/tokens.d.ts +91 -0
- package/dist/brand-kit/tokens.js +279 -0
- package/dist/brand-kit/types.d.ts +25 -0
- package/dist/client/AssistantChat.js +7 -7
- package/dist/client/onboarding/FirstRunOnboarding.js +26 -2
- package/dist/client/onboarding/first-run-registry.d.ts +25 -0
- package/dist/client/onboarding/first-run-registry.js +18 -0
- package/dist/client/onboarding/index.d.ts +2 -0
- package/dist/client/onboarding/index.js +1 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/migrations.d.ts +13 -3
- package/dist/db/migrations.js +19 -4
- package/dist/deploy/build.d.ts +8 -0
- package/dist/deploy/build.js +92 -3
- package/dist/deploy/workspace-deploy.js +86 -3
- package/dist/email-catalog/actions/list-email-activity.d.ts +5 -0
- package/dist/email-catalog/actions/list-email-activity.js +19 -0
- package/dist/email-catalog/actions/list-email-engagement.d.ts +5 -0
- package/dist/email-catalog/actions/list-email-engagement.js +15 -0
- package/dist/email-catalog/actions/list-email-log.d.ts +7 -0
- package/dist/email-catalog/actions/list-email-log.js +23 -0
- package/dist/email-catalog/actions/list-transactional-emails.d.ts +22 -0
- package/dist/email-catalog/actions/list-transactional-emails.js +67 -0
- package/dist/email-catalog/actions/render-transactional-email-preview.d.ts +9 -0
- package/dist/email-catalog/actions/render-transactional-email-preview.js +25 -0
- package/dist/email-catalog/authorize.d.ts +1 -0
- package/dist/email-catalog/authorize.js +9 -0
- package/dist/email-catalog/log.d.ts +60 -0
- package/dist/email-catalog/log.js +142 -0
- package/dist/email-catalog/provider-metrics.d.ts +34 -0
- package/dist/email-catalog/provider-metrics.js +182 -0
- package/dist/email-catalog/registry.d.ts +78 -0
- package/dist/email-catalog/registry.js +70 -0
- package/dist/email-catalog/schema.d.ts +231 -0
- package/dist/email-catalog/schema.js +53 -0
- package/dist/email-catalog/system-emails.d.ts +13 -0
- package/dist/email-catalog/system-emails.js +67 -0
- package/dist/jobs/index.d.ts +2 -0
- package/dist/jobs/index.js +2 -0
- package/dist/jobs/run-history.js +48 -1
- package/dist/jobs/scheduler-dispatch.d.ts +7 -0
- package/dist/jobs/scheduler-dispatch.js +7 -0
- package/dist/jobs/scheduler-health.d.ts +22 -0
- package/dist/jobs/scheduler-health.js +172 -0
- package/dist/jobs/scheduler.js +67 -2
- package/dist/localization/default-messages.d.ts +45 -0
- package/dist/localization/default-messages.js +45 -0
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/handlers.js +9 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/server/action-discovery.js +22 -0
- package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +7 -1
- package/dist/server/agent-chat/recurring-jobs-runtime.js +12 -0
- package/dist/server/agent-chat-plugin.d.ts +2 -1
- package/dist/server/agent-chat-plugin.js +69 -22
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/better-auth-instance.js +17 -2
- package/dist/server/design-token-utils.d.ts +6 -1
- package/dist/server/design-token-utils.js +252 -59
- package/dist/server/email.d.ts +11 -0
- package/dist/server/email.js +54 -3
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.js +3 -2
- package/dist/vite/client.js +20 -14
- package/package.json +2 -1
|
@@ -218,13 +218,14 @@ export default function PromptPopover({
|
|
|
218
218
|
)}
|
|
219
219
|
<div
|
|
220
220
|
ref={panelRef}
|
|
221
|
-
className="fixed z-[200] w-[min(
|
|
221
|
+
className="fixed z-[200] w-[min(500px,calc(100vw-24px))] rounded-xl border border-border/80 bg-popover shadow-xl shadow-black/15"
|
|
222
|
+
role="dialog"
|
|
223
|
+
aria-modal="true"
|
|
224
|
+
aria-label={title}
|
|
222
225
|
style={{ top: 0, left: 0, visibility: "visible" }}
|
|
223
226
|
>
|
|
224
|
-
<div className="flex items-center justify-between gap-3 px-
|
|
225
|
-
<span className="text-sm font-medium text-foreground
|
|
226
|
-
{title}
|
|
227
|
-
</span>
|
|
227
|
+
<div className="flex items-center justify-between gap-3 px-4 pb-2.5 pt-3.5">
|
|
228
|
+
<span className="text-sm font-medium text-foreground">{title}</span>
|
|
228
229
|
{onSkip && (
|
|
229
230
|
<button
|
|
230
231
|
type="button"
|
|
@@ -232,14 +233,14 @@ export default function PromptPopover({
|
|
|
232
233
|
onSkip();
|
|
233
234
|
onOpenChange(false);
|
|
234
235
|
}}
|
|
235
|
-
className="shrink-0
|
|
236
|
+
className="shrink-0 text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
236
237
|
>
|
|
237
238
|
{skipLabel}
|
|
238
239
|
</button>
|
|
239
240
|
)}
|
|
240
241
|
</div>
|
|
241
242
|
|
|
242
|
-
<div className="px-2 pb-2">
|
|
243
|
+
<div className="px-2.5 pb-2.5">
|
|
243
244
|
<PromptComposer
|
|
244
245
|
autoFocus
|
|
245
246
|
attachmentsEnabled
|
|
@@ -49,7 +49,9 @@ export function Layout({ children }: LayoutProps) {
|
|
|
49
49
|
useState<EditorSidebarOverride | null>(null);
|
|
50
50
|
const { collapsed: sidebarCollapsed, setCollapsed: setSidebarCollapsed } =
|
|
51
51
|
useSidebarCollapsed();
|
|
52
|
-
const { getDeck } = useDecks();
|
|
52
|
+
const { decks, getDeck, loading: decksLoading } = useDecks();
|
|
53
|
+
const isEmptyDecksState =
|
|
54
|
+
location.pathname === "/" && !decksLoading && decks.length === 0;
|
|
53
55
|
|
|
54
56
|
// Scope new chats to the deck the user is currently editing. The route
|
|
55
57
|
// is `/deck/:id`; everywhere else (list, presentation) leaves
|
|
@@ -124,28 +126,30 @@ export function Layout({ children }: LayoutProps) {
|
|
|
124
126
|
onClick={() => setSidebarOpen(false)}
|
|
125
127
|
/>
|
|
126
128
|
)}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
129
|
+
{!isEmptyDecksState && (
|
|
130
|
+
<div
|
|
131
|
+
className={cn(
|
|
132
|
+
"agent-layout-left-drawer fixed inset-y-0 start-0 z-50 transition-transform duration-200 ease-out md:static md:z-auto md:transition-none",
|
|
133
|
+
sidebarOpen
|
|
134
|
+
? "translate-x-0"
|
|
135
|
+
: "-translate-x-full rtl:translate-x-full md:translate-x-0 md:rtl:translate-x-0",
|
|
136
|
+
)}
|
|
137
|
+
>
|
|
138
|
+
<Sidebar
|
|
139
|
+
collapsed={effectiveSidebarCollapsed && !sidebarOpen}
|
|
140
|
+
// In the mobile drawer the sidebar is forced expanded, so the
|
|
141
|
+
// desktop collapse toggle would be a silent no-op (worse: it'd
|
|
142
|
+
// mutate the desktop preference). Hide it while the drawer is
|
|
143
|
+
// open.
|
|
144
|
+
onToggleCollapsed={
|
|
145
|
+
sidebarOpen ? undefined : toggleSidebarCollapsed
|
|
146
|
+
}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
146
150
|
<div className="agent-layout-main-surface flex h-full min-w-0 flex-1 flex-col overflow-hidden">
|
|
147
151
|
{/* Mobile-only nav strip with hamburger — only when there's no page toolbar */}
|
|
148
|
-
{!ownToolbar && (
|
|
152
|
+
{!isEmptyDecksState && !ownToolbar && (
|
|
149
153
|
<div className="flex h-12 items-center border-b border-border px-4 md:hidden shrink-0">
|
|
150
154
|
<button
|
|
151
155
|
onClick={() => setSidebarOpen(true)}
|
|
@@ -156,8 +160,8 @@ export function Layout({ children }: LayoutProps) {
|
|
|
156
160
|
</button>
|
|
157
161
|
</div>
|
|
158
162
|
)}
|
|
159
|
-
{!ownToolbar && <Header />}
|
|
160
|
-
<InvitationBanner />
|
|
163
|
+
{!isEmptyDecksState && !ownToolbar && <Header />}
|
|
164
|
+
{!isEmptyDecksState && <InvitationBanner />}
|
|
161
165
|
<main
|
|
162
166
|
className={cn(
|
|
163
167
|
"agent-native-app-main min-h-0 flex-1",
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { PromptComposer } from "@agent-native/core/client/composer";
|
|
2
|
+
import { callAction, useSession } from "@agent-native/core/client/hooks";
|
|
3
|
+
import { useT } from "@agent-native/core/client/i18n";
|
|
4
|
+
import type { FirstRunOnboardingExtensionProps } from "@agent-native/core/client/onboarding";
|
|
5
|
+
import { IconArrowLeft } from "@tabler/icons-react";
|
|
6
|
+
import { useCallback, useEffect, useState } from "react";
|
|
7
|
+
import { useNavigate, useSearchParams } from "react-router";
|
|
8
|
+
import { toast } from "sonner";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
NewDeckReferenceStep,
|
|
12
|
+
type NewDeckReferenceSelection,
|
|
13
|
+
} from "@/components/editor/NewDeckReferenceStep";
|
|
14
|
+
import {
|
|
15
|
+
uploadPromptFiles,
|
|
16
|
+
type UploadedFile,
|
|
17
|
+
} from "@/components/editor/PromptDialog";
|
|
18
|
+
import { useDecks } from "@/context/DeckContext";
|
|
19
|
+
import { useAgentGenerating } from "@/hooks/use-agent-generating";
|
|
20
|
+
import { useDesignSystems } from "@/hooks/use-design-systems";
|
|
21
|
+
import { useWorkspaceDefaults } from "@/hooks/use-workspace-defaults";
|
|
22
|
+
import { startDeckGeneration } from "@/lib/create-deck-generation";
|
|
23
|
+
import {
|
|
24
|
+
readRecentReferences,
|
|
25
|
+
rememberRecentReference,
|
|
26
|
+
type RecentReference,
|
|
27
|
+
} from "@/lib/recent-references";
|
|
28
|
+
|
|
29
|
+
type FirstDeckStep = "prompt" | "references";
|
|
30
|
+
|
|
31
|
+
export function FirstDeckOnboardingFlow({
|
|
32
|
+
onComplete,
|
|
33
|
+
onSkip,
|
|
34
|
+
}: FirstRunOnboardingExtensionProps) {
|
|
35
|
+
const t = useT();
|
|
36
|
+
const navigate = useNavigate();
|
|
37
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
38
|
+
const { session } = useSession();
|
|
39
|
+
const { decks, createDeck, ensureDeckPersisted, deleteDeck, reloadDecks } =
|
|
40
|
+
useDecks();
|
|
41
|
+
const { designSystems, defaultSystem } = useDesignSystems();
|
|
42
|
+
const {
|
|
43
|
+
referenceDeck: workspaceReferenceDeck,
|
|
44
|
+
designSystem: workspaceDesignSystem,
|
|
45
|
+
} = useWorkspaceDefaults();
|
|
46
|
+
const { submit: agentSubmit } = useAgentGenerating();
|
|
47
|
+
const [step, setStep] = useState<FirstDeckStep>("prompt");
|
|
48
|
+
const [prompt, setPrompt] = useState("");
|
|
49
|
+
const [promptFiles, setPromptFiles] = useState<UploadedFile[]>([]);
|
|
50
|
+
const [promptInitialText, setPromptInitialText] = useState<string>();
|
|
51
|
+
const [promptInitialTextKey, setPromptInitialTextKey] = useState<number>();
|
|
52
|
+
const [uploading, setUploading] = useState(false);
|
|
53
|
+
const [referenceImporting, setReferenceImporting] = useState(false);
|
|
54
|
+
const [recentReferences, setRecentReferences] = useState<RecentReference[]>(
|
|
55
|
+
[],
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const initialPrompt = searchParams.get("initialPrompt")?.trim() ?? "";
|
|
59
|
+
const workspaceReferenceDeckId =
|
|
60
|
+
workspaceReferenceDeck && !workspaceReferenceDeck.unavailable
|
|
61
|
+
? workspaceReferenceDeck.id
|
|
62
|
+
: null;
|
|
63
|
+
const workspaceDesignSystemId =
|
|
64
|
+
workspaceDesignSystem && !workspaceDesignSystem.unavailable
|
|
65
|
+
? workspaceDesignSystem.id
|
|
66
|
+
: null;
|
|
67
|
+
const initialDesignSystemId =
|
|
68
|
+
designSystems.find((designSystem) => designSystem.isDefault)?.id ??
|
|
69
|
+
workspaceDesignSystemId ??
|
|
70
|
+
defaultSystem?.id ??
|
|
71
|
+
null;
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const result = readRecentReferences();
|
|
75
|
+
if (result.readable) setRecentReferences(result.items);
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!initialPrompt) return;
|
|
80
|
+
setPromptInitialText(initialPrompt);
|
|
81
|
+
setPromptInitialTextKey(Date.now());
|
|
82
|
+
setSearchParams(
|
|
83
|
+
(previous) => {
|
|
84
|
+
const next = new URLSearchParams(previous);
|
|
85
|
+
next.delete("initialPrompt");
|
|
86
|
+
return next;
|
|
87
|
+
},
|
|
88
|
+
{ replace: true },
|
|
89
|
+
);
|
|
90
|
+
}, [initialPrompt, setSearchParams]);
|
|
91
|
+
|
|
92
|
+
const rememberReference = useCallback(
|
|
93
|
+
(reference: Omit<RecentReference, "lastUsedAt">) => {
|
|
94
|
+
const result = rememberRecentReference(reference);
|
|
95
|
+
if (result.readable) setRecentReferences(result.items);
|
|
96
|
+
},
|
|
97
|
+
[],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const handlePromptSubmit = useCallback(
|
|
101
|
+
async (text: string, files: File[]) => {
|
|
102
|
+
setUploading(true);
|
|
103
|
+
try {
|
|
104
|
+
const uploaded = await uploadPromptFiles(files);
|
|
105
|
+
setPrompt(text.trim());
|
|
106
|
+
setPromptFiles(uploaded);
|
|
107
|
+
setStep("references");
|
|
108
|
+
} catch (error) {
|
|
109
|
+
toast.error(t("raw.uploadFailed"), {
|
|
110
|
+
description:
|
|
111
|
+
error instanceof Error
|
|
112
|
+
? error.message
|
|
113
|
+
: t("raw.uploadAttachedFailed"),
|
|
114
|
+
});
|
|
115
|
+
} finally {
|
|
116
|
+
setUploading(false);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
[t],
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const startGeneration = useCallback(
|
|
123
|
+
async (
|
|
124
|
+
files: UploadedFile[],
|
|
125
|
+
selection: NewDeckReferenceSelection = {},
|
|
126
|
+
) => {
|
|
127
|
+
const result = await startDeckGeneration({
|
|
128
|
+
session,
|
|
129
|
+
prompt,
|
|
130
|
+
files,
|
|
131
|
+
referenceSelection: selection,
|
|
132
|
+
selectedDesignSystemId: initialDesignSystemId,
|
|
133
|
+
selectedReferenceDeckId: workspaceReferenceDeckId,
|
|
134
|
+
designSystems,
|
|
135
|
+
createDeck,
|
|
136
|
+
ensureDeckPersisted,
|
|
137
|
+
deleteDeck,
|
|
138
|
+
navigate,
|
|
139
|
+
agentSubmit,
|
|
140
|
+
onPromptClosed: () => undefined,
|
|
141
|
+
onUnauthenticated: () => {
|
|
142
|
+
toast.error(t("home.signInTitle"));
|
|
143
|
+
},
|
|
144
|
+
onPersistenceFailure: (failedPrompt) => {
|
|
145
|
+
setPromptInitialText(failedPrompt);
|
|
146
|
+
setPromptInitialTextKey(Date.now());
|
|
147
|
+
setStep("prompt");
|
|
148
|
+
toast.error(t("home.generationStartFailed"), {
|
|
149
|
+
description: t("home.generationStartFailedDescription"),
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
if (result === "started") onComplete();
|
|
154
|
+
},
|
|
155
|
+
[
|
|
156
|
+
agentSubmit,
|
|
157
|
+
createDeck,
|
|
158
|
+
deleteDeck,
|
|
159
|
+
designSystems,
|
|
160
|
+
ensureDeckPersisted,
|
|
161
|
+
initialDesignSystemId,
|
|
162
|
+
navigate,
|
|
163
|
+
onComplete,
|
|
164
|
+
prompt,
|
|
165
|
+
session,
|
|
166
|
+
t,
|
|
167
|
+
workspaceReferenceDeckId,
|
|
168
|
+
],
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const handleReferenceSelect = useCallback(
|
|
172
|
+
async (selection: NewDeckReferenceSelection) => {
|
|
173
|
+
if (selection.designSystemId) {
|
|
174
|
+
rememberReference({
|
|
175
|
+
id: selection.designSystemId,
|
|
176
|
+
kind: "design-system",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (selection.referenceDeckId) {
|
|
180
|
+
rememberReference({ id: selection.referenceDeckId, kind: "deck" });
|
|
181
|
+
}
|
|
182
|
+
await startGeneration(promptFiles, selection);
|
|
183
|
+
},
|
|
184
|
+
[promptFiles, rememberReference, startGeneration],
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const handleReferenceImport = useCallback(
|
|
188
|
+
async (files: File[]) => {
|
|
189
|
+
setReferenceImporting(true);
|
|
190
|
+
try {
|
|
191
|
+
const uploaded = await uploadPromptFiles(files);
|
|
192
|
+
const pptxReference = uploaded.find((file) =>
|
|
193
|
+
file.originalName.toLowerCase().endsWith(".pptx"),
|
|
194
|
+
);
|
|
195
|
+
let referenceSelection: NewDeckReferenceSelection = {
|
|
196
|
+
designSystemId: null,
|
|
197
|
+
referenceDeckId: null,
|
|
198
|
+
};
|
|
199
|
+
let generationFiles = uploaded;
|
|
200
|
+
if (pptxReference) {
|
|
201
|
+
const imported = (await callAction("import-pptx", {
|
|
202
|
+
filePath: pptxReference.path,
|
|
203
|
+
})) as { id?: unknown };
|
|
204
|
+
if (typeof imported.id !== "string" || !imported.id) {
|
|
205
|
+
throw new Error("The imported presentation did not create a deck.");
|
|
206
|
+
}
|
|
207
|
+
await reloadDecks();
|
|
208
|
+
rememberReference({ id: imported.id, kind: "deck" });
|
|
209
|
+
referenceSelection = {
|
|
210
|
+
designSystemId: null,
|
|
211
|
+
referenceDeckId: imported.id,
|
|
212
|
+
};
|
|
213
|
+
generationFiles = uploaded.filter((file) => file !== pptxReference);
|
|
214
|
+
}
|
|
215
|
+
await startGeneration(
|
|
216
|
+
[...promptFiles, ...generationFiles],
|
|
217
|
+
referenceSelection,
|
|
218
|
+
);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
toast.error(t("editorToolbar.uploadFailed"), {
|
|
221
|
+
description:
|
|
222
|
+
error instanceof Error
|
|
223
|
+
? error.message
|
|
224
|
+
: t("editorToolbar.importFailedDescription"),
|
|
225
|
+
});
|
|
226
|
+
} finally {
|
|
227
|
+
setReferenceImporting(false);
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
[promptFiles, reloadDecks, rememberReference, startGeneration, t],
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const handleReferenceSkip = useCallback(() => {
|
|
234
|
+
void startGeneration(promptFiles, {
|
|
235
|
+
designSystemId: null,
|
|
236
|
+
referenceDeckId: null,
|
|
237
|
+
});
|
|
238
|
+
}, [promptFiles, startGeneration]);
|
|
239
|
+
|
|
240
|
+
if (step === "references") {
|
|
241
|
+
return (
|
|
242
|
+
<NewDeckReferenceStep
|
|
243
|
+
open
|
|
244
|
+
decks={decks}
|
|
245
|
+
designSystems={designSystems}
|
|
246
|
+
defaultDesignSystemId={initialDesignSystemId}
|
|
247
|
+
defaultReferenceDeckId={workspaceReferenceDeckId}
|
|
248
|
+
recentReferences={recentReferences}
|
|
249
|
+
onSelect={handleReferenceSelect}
|
|
250
|
+
onImport={handleReferenceImport}
|
|
251
|
+
onSkip={handleReferenceSkip}
|
|
252
|
+
onOpenChange={(open) => {
|
|
253
|
+
if (!open) setStep("prompt");
|
|
254
|
+
}}
|
|
255
|
+
importing={referenceImporting}
|
|
256
|
+
title={t("home.newDeck")}
|
|
257
|
+
designSystemLabel={t("home.designSystem")}
|
|
258
|
+
referenceDeckLabel={t("home.referenceDeck")}
|
|
259
|
+
chooseDeckLabel={t("home.referenceDeckPlaceholder")}
|
|
260
|
+
importingLabel={t("raw.uploading")}
|
|
261
|
+
skipLabel={t("home.referenceDeckNone")}
|
|
262
|
+
defaultSuffix={t("home.defaultSuffix")}
|
|
263
|
+
starredLabel={t("home.referenceDeckStarredGroup")}
|
|
264
|
+
otherDecksLabel={t("home.referenceDeckOtherGroup")}
|
|
265
|
+
searchDecksLabel={t("root.searchDecks")}
|
|
266
|
+
promptSummary={prompt}
|
|
267
|
+
/>
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
<div
|
|
273
|
+
className="fixed inset-0 z-[200] flex min-h-screen flex-col bg-background text-foreground"
|
|
274
|
+
role="dialog"
|
|
275
|
+
aria-modal="true"
|
|
276
|
+
aria-label={t("home.firstDeckPromptTitle")}
|
|
277
|
+
>
|
|
278
|
+
<header className="flex h-14 shrink-0 items-center justify-between border-b border-border px-5 sm:px-8">
|
|
279
|
+
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
280
|
+
<IconArrowLeft className="size-4" />
|
|
281
|
+
<span>{t("home.newDeck")}</span>
|
|
282
|
+
</div>
|
|
283
|
+
<button
|
|
284
|
+
type="button"
|
|
285
|
+
onClick={onSkip}
|
|
286
|
+
className="text-xs text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
287
|
+
>
|
|
288
|
+
{t("home.firstDeckSkip")}
|
|
289
|
+
</button>
|
|
290
|
+
</header>
|
|
291
|
+
<main className="flex min-h-0 flex-1 items-center justify-center overflow-y-auto px-5 py-10 sm:px-8">
|
|
292
|
+
<div className="w-full max-w-xl">
|
|
293
|
+
<h1 className="text-center text-2xl font-semibold tracking-[-0.04em] sm:text-3xl">
|
|
294
|
+
{t("home.firstDeckPromptTitle")}
|
|
295
|
+
</h1>
|
|
296
|
+
<PromptComposer
|
|
297
|
+
className="mt-8"
|
|
298
|
+
autoFocus
|
|
299
|
+
attachmentsEnabled
|
|
300
|
+
disabled={uploading}
|
|
301
|
+
placeholder={t("home.newDeckPlaceholder")}
|
|
302
|
+
onSubmit={handlePromptSubmit}
|
|
303
|
+
draftScope="slides-first-deck"
|
|
304
|
+
initialText={promptInitialText}
|
|
305
|
+
initialTextKey={promptInitialTextKey}
|
|
306
|
+
/>
|
|
307
|
+
</div>
|
|
308
|
+
</main>
|
|
309
|
+
</div>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export default FirstDeckOnboardingFlow;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@agent-native/toolkit/ui/command";
|
|
@@ -664,10 +664,15 @@ const messages = {
|
|
|
664
664
|
newDeckPromptTitle: "New deck",
|
|
665
665
|
newDeckPlaceholder: "Describe your deck, visual, or diagram...",
|
|
666
666
|
skipPrompt: "Skip prompt",
|
|
667
|
+
firstDeckPromptTitle: "What do you want to make?",
|
|
668
|
+
firstDeckSkip: "Skip",
|
|
669
|
+
chooseReferences: "Choose references",
|
|
670
|
+
addDesignSystem: "+ Design system",
|
|
671
|
+
importFrom: "Import from",
|
|
667
672
|
designSystem: "Design system",
|
|
668
673
|
referenceDeck: "Reference deck",
|
|
669
674
|
referenceDeckPlaceholder: "Match the style of an existing deck",
|
|
670
|
-
referenceDeckNone: "
|
|
675
|
+
referenceDeckNone: "Skip",
|
|
671
676
|
referenceDeckStarredGroup: "Starred",
|
|
672
677
|
referenceDeckOtherGroup: "Other decks",
|
|
673
678
|
referenceReviewTitle: "Review references",
|
|
@@ -708,7 +713,8 @@ const messages = {
|
|
|
708
713
|
signInDescriptionWithFiles:
|
|
709
714
|
"You need to sign in before generating a deck. We've saved your prompt; reattach any files once you're back.",
|
|
710
715
|
signIn: "Sign in",
|
|
711
|
-
emptyTitle: "
|
|
716
|
+
emptyTitle: "No decks yet",
|
|
717
|
+
createFirstDeck: "Create your first deck",
|
|
712
718
|
emptyDescription:
|
|
713
719
|
"Build beautiful presentations, standalone visuals, diagrams, and image-rich stories with AI-powered generation.",
|
|
714
720
|
},
|