@agent-native/core 0.141.3 → 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-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 +11 -3
- 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/routes.d.ts +1 -1
- 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 +5 -5
- 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/secrets/routes.d.ts +9 -9
- 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 +39 -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 +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/vite/client.js +20 -14
- package/package.json +2 -1
|
@@ -20,7 +20,10 @@ import { useLocation, useNavigate, useSearchParams } from "react-router";
|
|
|
20
20
|
import { toast } from "sonner";
|
|
21
21
|
|
|
22
22
|
import DeckCard from "@/components/deck/DeckCard";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
NewDeckReferenceStep,
|
|
25
|
+
type NewDeckReferenceSelection,
|
|
26
|
+
} from "@/components/editor/NewDeckReferenceStep";
|
|
24
27
|
import PromptPopover, {
|
|
25
28
|
uploadPromptFiles,
|
|
26
29
|
type UploadedFile,
|
|
@@ -46,10 +49,10 @@ import { createDeckAgentMessage } from "@/lib/agent-visible-message";
|
|
|
46
49
|
import { savePromptToComposerDraft } from "@/lib/composer-draft";
|
|
47
50
|
import { sortDecksByRecency } from "@/lib/deck-sorting";
|
|
48
51
|
import {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
readRecentReferences,
|
|
53
|
+
rememberRecentReference,
|
|
54
|
+
type RecentReference,
|
|
55
|
+
} from "@/lib/recent-references";
|
|
53
56
|
|
|
54
57
|
const NEW_DECK_DRAFT_SCOPE = "slides-new-deck";
|
|
55
58
|
const PENDING_PROMPT_KEY = "slides:pending-deck-prompt";
|
|
@@ -237,6 +240,9 @@ export default function Index() {
|
|
|
237
240
|
} | null>(null);
|
|
238
241
|
const [showNewDeckReferenceStep, setShowNewDeckReferenceStep] =
|
|
239
242
|
useState(false);
|
|
243
|
+
const [recentReferences, setRecentReferences] = useState<RecentReference[]>(
|
|
244
|
+
[],
|
|
245
|
+
);
|
|
240
246
|
const [referenceImporting, setReferenceImporting] = useState(false);
|
|
241
247
|
const initialPromptConsumedRef = useRef(false);
|
|
242
248
|
const [signInPromptHadFiles, setSignInPromptHadFiles] = useState(false);
|
|
@@ -296,11 +302,18 @@ export default function Index() {
|
|
|
296
302
|
[deckFilter, decks],
|
|
297
303
|
);
|
|
298
304
|
const rememberReference = useCallback(
|
|
299
|
-
(reference: Parameters<typeof rememberRecentReference>[0]) =>
|
|
300
|
-
rememberRecentReference(reference)
|
|
305
|
+
(reference: Parameters<typeof rememberRecentReference>[0]) => {
|
|
306
|
+
const result = rememberRecentReference(reference);
|
|
307
|
+
if (result.readable) setRecentReferences(result.items);
|
|
308
|
+
},
|
|
301
309
|
[],
|
|
302
310
|
);
|
|
303
311
|
|
|
312
|
+
useEffect(() => {
|
|
313
|
+
const result = readRecentReferences();
|
|
314
|
+
if (result.readable) setRecentReferences(result.items);
|
|
315
|
+
}, []);
|
|
316
|
+
|
|
304
317
|
useEffect(() => {
|
|
305
318
|
if (initialDesignSystemId) {
|
|
306
319
|
rememberReference({
|
|
@@ -314,15 +327,13 @@ export default function Index() {
|
|
|
314
327
|
}, [initialDesignSystemId, rememberReference, workspaceReferenceDeckId]);
|
|
315
328
|
|
|
316
329
|
const initialPrompt = searchParams.get("initialPrompt")?.trim() ?? "";
|
|
317
|
-
const
|
|
330
|
+
const onboardingPreview = searchParams.get("onboarding") === "preview";
|
|
331
|
+
const openInitialPrompt = useCallback(() => {
|
|
318
332
|
if (!initialPrompt || initialPromptConsumedRef.current) return;
|
|
319
333
|
initialPromptConsumedRef.current = true;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
setSelectedDesignSystemId(initialDesignSystemId ?? null);
|
|
324
|
-
setSelectedReferenceDeckId(workspaceReferenceDeckId ?? null);
|
|
325
|
-
setShowNewDeckReferenceStep(true);
|
|
334
|
+
anchorElRef.current = null;
|
|
335
|
+
setNewDeckInitialPrompt({ text: initialPrompt, key: Date.now() });
|
|
336
|
+
setShowNewDeckPrompt(true);
|
|
326
337
|
setSearchParams(
|
|
327
338
|
(previous) => {
|
|
328
339
|
const next = new URLSearchParams(previous);
|
|
@@ -336,22 +347,39 @@ export default function Index() {
|
|
|
336
347
|
useEffect(() => {
|
|
337
348
|
if (!initialPrompt || initialPromptConsumedRef.current) return;
|
|
338
349
|
const firstRunActive =
|
|
339
|
-
|
|
340
|
-
document
|
|
341
|
-
.
|
|
342
|
-
|
|
343
|
-
|
|
350
|
+
onboardingPreview ||
|
|
351
|
+
(typeof document !== "undefined" &&
|
|
352
|
+
document.cookie
|
|
353
|
+
.split(";")
|
|
354
|
+
.some((part) => part.trim().startsWith("agent-native-first-run=")));
|
|
355
|
+
const handleFirstRunCompleted = () => openInitialPrompt();
|
|
344
356
|
window.addEventListener(
|
|
345
357
|
"agent-native:first-run-completed",
|
|
346
358
|
handleFirstRunCompleted,
|
|
347
359
|
);
|
|
348
|
-
|
|
349
|
-
|
|
360
|
+
let fallbackTimer: number | undefined;
|
|
361
|
+
if (!firstRunActive) {
|
|
362
|
+
openInitialPrompt();
|
|
363
|
+
} else {
|
|
364
|
+
// A landing link can open in a tab where the first-run marker exists but
|
|
365
|
+
// the onboarding surface is not mounted. Do not leave the prompt waiting
|
|
366
|
+
// forever in that case, while still giving the real onboarding overlay
|
|
367
|
+
// time to load and dispatch its completion event.
|
|
368
|
+
fallbackTimer = window.setTimeout(() => {
|
|
369
|
+
const firstRunSurface = document.querySelector(
|
|
370
|
+
"[data-onboarding-screen], [data-onboarding-loading]",
|
|
371
|
+
);
|
|
372
|
+
if (!firstRunSurface) openInitialPrompt();
|
|
373
|
+
}, 2500);
|
|
374
|
+
}
|
|
375
|
+
return () => {
|
|
350
376
|
window.removeEventListener(
|
|
351
377
|
"agent-native:first-run-completed",
|
|
352
378
|
handleFirstRunCompleted,
|
|
353
379
|
);
|
|
354
|
-
|
|
380
|
+
if (fallbackTimer !== undefined) window.clearTimeout(fallbackTimer);
|
|
381
|
+
};
|
|
382
|
+
}, [initialPrompt, onboardingPreview, openInitialPrompt]);
|
|
355
383
|
|
|
356
384
|
const setDeckFilter = useCallback(
|
|
357
385
|
(value: string) => {
|
|
@@ -504,7 +532,7 @@ export default function Index() {
|
|
|
504
532
|
const handleCreateDeckWithPrompt = async (
|
|
505
533
|
prompt: string,
|
|
506
534
|
files: UploadedFile[],
|
|
507
|
-
referenceSelection:
|
|
535
|
+
referenceSelection: NewDeckReferenceSelection = {},
|
|
508
536
|
) => {
|
|
509
537
|
// Pre-flight auth check. The add-deck action returns 403 silently
|
|
510
538
|
// when unauthenticated, leaving the user stuck on a deck page that
|
|
@@ -520,22 +548,14 @@ export default function Index() {
|
|
|
520
548
|
newDeckRetryFiles,
|
|
521
549
|
files,
|
|
522
550
|
);
|
|
523
|
-
const resolvedSelection = resolveNewDeckReferenceSelection({
|
|
524
|
-
designSystemAuto: designSystemAutoRef.current,
|
|
525
|
-
selectedDesignSystemId,
|
|
526
|
-
defaultDesignSystemId: initialDesignSystemId,
|
|
527
|
-
referenceDeckAuto: referenceDeckAutoRef.current,
|
|
528
|
-
selectedReferenceDeckId,
|
|
529
|
-
defaultReferenceDeckId: workspaceReferenceDeckId,
|
|
530
|
-
});
|
|
531
551
|
const designSystemId =
|
|
532
552
|
referenceSelection.designSystemId !== undefined
|
|
533
553
|
? referenceSelection.designSystemId
|
|
534
|
-
:
|
|
554
|
+
: selectedDesignSystemId;
|
|
535
555
|
const referenceDeckId =
|
|
536
556
|
referenceSelection.referenceDeckId !== undefined
|
|
537
557
|
? referenceSelection.referenceDeckId
|
|
538
|
-
:
|
|
558
|
+
: selectedReferenceDeckId;
|
|
539
559
|
const selectedDesignSystem = designSystemId
|
|
540
560
|
? designSystems.find((ds) => ds.id === designSystemId)
|
|
541
561
|
: undefined;
|
|
@@ -608,6 +628,19 @@ export default function Index() {
|
|
|
608
628
|
"Design system selection:",
|
|
609
629
|
"- None selected. Do not apply a design system unless the user asks for one.",
|
|
610
630
|
].join("\n");
|
|
631
|
+
const referenceSource = referenceSelection.referenceSource;
|
|
632
|
+
const referenceSourceContext = referenceSource
|
|
633
|
+
? [
|
|
634
|
+
"",
|
|
635
|
+
"Additional reference source selected in the reference step:",
|
|
636
|
+
`- ${referenceSource.kind}: ${referenceSource.value}`,
|
|
637
|
+
referenceSource.kind === "google-docs"
|
|
638
|
+
? "Call `import-google-doc` before generating and use the returned text as source material."
|
|
639
|
+
: referenceSource.kind === "website"
|
|
640
|
+
? "Call `import-from-url` before generating and use the returned page context as a reference."
|
|
641
|
+
: "Use the Figma source as the design reference. If Builder or Figma access is required, report the exact connection step instead of guessing.",
|
|
642
|
+
].join("\n")
|
|
643
|
+
: "";
|
|
611
644
|
|
|
612
645
|
const context = [
|
|
613
646
|
`The user just created a new empty deck (id: "${deckId}") and wants to create a presentation or standalone visual.`,
|
|
@@ -616,6 +649,7 @@ export default function Index() {
|
|
|
616
649
|
fileContext,
|
|
617
650
|
referenceDeckContext,
|
|
618
651
|
designSystemContext,
|
|
652
|
+
referenceSourceContext,
|
|
619
653
|
"",
|
|
620
654
|
"Before generating, if the request or selected references leave a meaningful choice unresolved, use the `ask-question` tool to ask one concise, prompt-specific question in the inline guided-question flow. Generate the question wording and 2 to 4 options from the user's request and selected references, like Claude's design-question flow; do not use a fixed generic questionnaire. Ask only a choice that materially affects the deck, such as audience, tone, structure, or length. If the prompt already makes the choice clear, do not ask it again. Wait for the user's answer or skip before adding slides.",
|
|
621
655
|
"Start a `manage-progress` run so progress appears in the app header. Add the first slide as soon as it is ready, then continue one slide at a time so the editor visibly fills in.",
|
|
@@ -652,64 +686,30 @@ export default function Index() {
|
|
|
652
686
|
[setNewDeckPromptOpen],
|
|
653
687
|
);
|
|
654
688
|
|
|
655
|
-
const
|
|
656
|
-
(
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
if (designSystemId) {
|
|
660
|
-
rememberReference({
|
|
689
|
+
const handleReferenceSelect = useCallback(
|
|
690
|
+
async (selection: NewDeckReferenceSelection) => {
|
|
691
|
+
const pending = pendingDeck;
|
|
692
|
+
if (!pending) return;
|
|
693
|
+
if (selection.designSystemId) {
|
|
694
|
+
rememberReference({
|
|
695
|
+
id: selection.designSystemId,
|
|
696
|
+
kind: "design-system",
|
|
697
|
+
});
|
|
661
698
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
);
|
|
665
|
-
|
|
666
|
-
const handleReferenceDeckSelect = useCallback(
|
|
667
|
-
(referenceDeckId: string | null) => {
|
|
668
|
-
referenceDeckAutoRef.current = false;
|
|
669
|
-
setSelectedReferenceDeckId(referenceDeckId);
|
|
670
|
-
if (referenceDeckId) {
|
|
671
|
-
rememberReference({ id: referenceDeckId, kind: "deck" });
|
|
699
|
+
if (selection.referenceDeckId) {
|
|
700
|
+
rememberReference({ id: selection.referenceDeckId, kind: "deck" });
|
|
672
701
|
}
|
|
702
|
+
setShowNewDeckReferenceStep(false);
|
|
703
|
+
setPendingDeck(null);
|
|
704
|
+
await handleCreateDeckWithPrompt(
|
|
705
|
+
pending.prompt,
|
|
706
|
+
pending.files,
|
|
707
|
+
selection,
|
|
708
|
+
);
|
|
673
709
|
},
|
|
674
|
-
[rememberReference],
|
|
675
|
-
);
|
|
676
|
-
|
|
677
|
-
const handleGoogleSlidesImported = useCallback(
|
|
678
|
-
async ({ id, title }: { id: string; title: string }) => {
|
|
679
|
-
await reloadDecks();
|
|
680
|
-
rememberReference({ id, kind: "deck" });
|
|
681
|
-
referenceDeckAutoRef.current = false;
|
|
682
|
-
setSelectedReferenceDeckId(id);
|
|
683
|
-
toast.success(t("editorToolbar.importComplete"), {
|
|
684
|
-
description: title,
|
|
685
|
-
});
|
|
686
|
-
},
|
|
687
|
-
[reloadDecks, rememberReference, t],
|
|
710
|
+
[handleCreateDeckWithPrompt, pendingDeck, rememberReference],
|
|
688
711
|
);
|
|
689
712
|
|
|
690
|
-
const handleReferenceContinue = useCallback(() => {
|
|
691
|
-
const pending = pendingDeck;
|
|
692
|
-
if (!pending) return;
|
|
693
|
-
setShowNewDeckReferenceStep(false);
|
|
694
|
-
setPendingDeck(null);
|
|
695
|
-
const selection = resolveNewDeckReferenceSelection({
|
|
696
|
-
designSystemAuto: designSystemAutoRef.current,
|
|
697
|
-
selectedDesignSystemId,
|
|
698
|
-
defaultDesignSystemId: initialDesignSystemId,
|
|
699
|
-
referenceDeckAuto: referenceDeckAutoRef.current,
|
|
700
|
-
selectedReferenceDeckId,
|
|
701
|
-
defaultReferenceDeckId: workspaceReferenceDeckId,
|
|
702
|
-
});
|
|
703
|
-
void handleCreateDeckWithPrompt(pending.prompt, pending.files, selection);
|
|
704
|
-
}, [
|
|
705
|
-
handleCreateDeckWithPrompt,
|
|
706
|
-
initialDesignSystemId,
|
|
707
|
-
pendingDeck,
|
|
708
|
-
selectedDesignSystemId,
|
|
709
|
-
selectedReferenceDeckId,
|
|
710
|
-
workspaceReferenceDeckId,
|
|
711
|
-
]);
|
|
712
|
-
|
|
713
713
|
const handleReferenceImport = useCallback(
|
|
714
714
|
async (files: File[]) => {
|
|
715
715
|
const pending = pendingDeck;
|
|
@@ -723,6 +723,10 @@ export default function Index() {
|
|
|
723
723
|
const pdfReference = uploaded.find((file) =>
|
|
724
724
|
file.originalName.toLowerCase().endsWith(".pdf"),
|
|
725
725
|
);
|
|
726
|
+
let referenceSelection: NewDeckReferenceSelection = {
|
|
727
|
+
designSystemId: null,
|
|
728
|
+
referenceDeckId: null,
|
|
729
|
+
};
|
|
726
730
|
if (pptxReference) {
|
|
727
731
|
const imported = (await callAction("import-pptx", {
|
|
728
732
|
filePath: pptxReference.path,
|
|
@@ -732,8 +736,11 @@ export default function Index() {
|
|
|
732
736
|
}
|
|
733
737
|
await reloadDecks();
|
|
734
738
|
rememberReference({ id: imported.id, kind: "deck" });
|
|
735
|
-
referenceDeckAutoRef.current = false;
|
|
736
739
|
setSelectedReferenceDeckId(imported.id);
|
|
740
|
+
referenceSelection = {
|
|
741
|
+
designSystemId: null,
|
|
742
|
+
referenceDeckId: imported.id,
|
|
743
|
+
};
|
|
737
744
|
}
|
|
738
745
|
if (!pptxReference && pdfReference) {
|
|
739
746
|
const referenceDeck = createDeck(undefined, {
|
|
@@ -759,8 +766,11 @@ export default function Index() {
|
|
|
759
766
|
}
|
|
760
767
|
await reloadDecks();
|
|
761
768
|
rememberReference({ id: referenceDeck.id, kind: "deck" });
|
|
762
|
-
referenceDeckAutoRef.current = false;
|
|
763
769
|
setSelectedReferenceDeckId(referenceDeck.id);
|
|
770
|
+
referenceSelection = {
|
|
771
|
+
designSystemId: null,
|
|
772
|
+
referenceDeckId: referenceDeck.id,
|
|
773
|
+
};
|
|
764
774
|
} catch (error) {
|
|
765
775
|
deleteDeck(referenceDeck.id);
|
|
766
776
|
throw error;
|
|
@@ -770,19 +780,13 @@ export default function Index() {
|
|
|
770
780
|
const generationFiles = uploaded.filter(
|
|
771
781
|
(file) => file !== importedReference,
|
|
772
782
|
);
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
generationFiles,
|
|
781
|
-
),
|
|
782
|
-
}
|
|
783
|
-
: current,
|
|
784
|
-
);
|
|
785
|
-
}
|
|
783
|
+
setShowNewDeckReferenceStep(false);
|
|
784
|
+
setPendingDeck(null);
|
|
785
|
+
await handleCreateDeckWithPrompt(
|
|
786
|
+
pending.prompt,
|
|
787
|
+
[...pending.files, ...generationFiles],
|
|
788
|
+
referenceSelection,
|
|
789
|
+
);
|
|
786
790
|
} catch (error) {
|
|
787
791
|
toast.error(t("editorToolbar.uploadFailed"), {
|
|
788
792
|
description:
|
|
@@ -799,6 +803,7 @@ export default function Index() {
|
|
|
799
803
|
createDeck,
|
|
800
804
|
deleteDeck,
|
|
801
805
|
ensureDeckPersisted,
|
|
806
|
+
handleCreateDeckWithPrompt,
|
|
802
807
|
pendingDeck,
|
|
803
808
|
reloadDecks,
|
|
804
809
|
rememberReference,
|
|
@@ -950,8 +955,8 @@ export default function Index() {
|
|
|
950
955
|
<main className="min-w-0 flex-1 overflow-y-auto px-4 py-6 sm:px-6 sm:py-10">
|
|
951
956
|
{loading ? (
|
|
952
957
|
<>
|
|
953
|
-
<div className="flex items-center justify-end
|
|
954
|
-
<div className="h-3 w-16 rounded bg-muted
|
|
958
|
+
<div className="mb-4 flex items-center justify-end">
|
|
959
|
+
<div className="h-3 w-16 animate-pulse rounded bg-muted" />
|
|
955
960
|
</div>
|
|
956
961
|
<div className="deck-grid-container">
|
|
957
962
|
<div className="deck-grid grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
|
@@ -1150,45 +1155,36 @@ export default function Index() {
|
|
|
1150
1155
|
<NewDeckReferenceStep
|
|
1151
1156
|
open={showNewDeckReferenceStep}
|
|
1152
1157
|
onOpenChange={(open) => {
|
|
1153
|
-
if (!open)
|
|
1158
|
+
if (!open) {
|
|
1159
|
+
const prompt = pendingDeck?.prompt;
|
|
1160
|
+
setShowNewDeckReferenceStep(false);
|
|
1161
|
+
setPendingDeck(null);
|
|
1162
|
+
if (prompt) {
|
|
1163
|
+
setNewDeckInitialPrompt({ text: prompt, key: Date.now() });
|
|
1164
|
+
setShowNewDeckPrompt(true);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1154
1167
|
}}
|
|
1155
1168
|
designSystems={designSystems}
|
|
1156
1169
|
decks={decks}
|
|
1157
1170
|
defaultDesignSystemId={initialDesignSystemId}
|
|
1158
1171
|
defaultReferenceDeckId={workspaceReferenceDeckId}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
onSelectDesignSystem={handleReferenceDesignSystemSelect}
|
|
1162
|
-
onSelectReferenceDeck={handleReferenceDeckSelect}
|
|
1172
|
+
recentReferences={recentReferences}
|
|
1173
|
+
onSelect={(selection) => void handleReferenceSelect(selection)}
|
|
1163
1174
|
onImport={handleReferenceImport}
|
|
1164
|
-
onGoogleSlidesImported={handleGoogleSlidesImported}
|
|
1165
|
-
onContinue={handleReferenceContinue}
|
|
1166
1175
|
onSkip={handleReferenceSkip}
|
|
1167
1176
|
importing={referenceImporting}
|
|
1168
|
-
title={t("home.
|
|
1169
|
-
description={t("home.referenceReviewDescription")}
|
|
1177
|
+
title={t("home.newDeckPromptTitle")}
|
|
1170
1178
|
designSystemLabel={t("home.designSystem")}
|
|
1171
1179
|
referenceDeckLabel={t("home.referenceDeck")}
|
|
1172
|
-
|
|
1173
|
-
importFileLabel={t("editorToolbar.importFile")}
|
|
1180
|
+
chooseDeckLabel={t("home.referenceDeckPlaceholder")}
|
|
1174
1181
|
importingLabel={t("editorToolbar.importing")}
|
|
1175
|
-
|
|
1176
|
-
skipLabel={t("home.skipReferences")}
|
|
1182
|
+
skipLabel={t("home.referenceDeckNone")}
|
|
1177
1183
|
defaultSuffix={t("home.defaultSuffix")}
|
|
1178
1184
|
starredLabel={t("home.referenceDeckStarredGroup")}
|
|
1179
1185
|
otherDecksLabel={t("home.referenceDeckOtherGroup")}
|
|
1180
1186
|
searchDecksLabel={t("root.searchDecks")}
|
|
1181
|
-
|
|
1182
|
-
noMatchingDecksLabel={t("home.noMatchingDecks")}
|
|
1183
|
-
googleSlidesTitle={t("home.googleSlidesReferenceTitle")}
|
|
1184
|
-
googleSlidesConnectLabel={t("home.googleSlidesReferenceConnect")}
|
|
1185
|
-
googleSlidesChooseLabel={t("home.googleSlidesReferenceChoose")}
|
|
1186
|
-
googleSlidesPickingLabel={t("home.googleSlidesReferencePicking")}
|
|
1187
|
-
googleSlidesConnectedLabel={t("home.googleSlidesReferenceConnected")}
|
|
1188
|
-
googleSlidesUnavailableLabel={t(
|
|
1189
|
-
"home.googleSlidesReferenceUnavailable",
|
|
1190
|
-
)}
|
|
1191
|
-
promptNote={pendingDeck?.prompt}
|
|
1187
|
+
promptSummary={pendingDeck?.prompt}
|
|
1192
1188
|
/>
|
|
1193
1189
|
|
|
1194
1190
|
{/* Sign-in required to create a deck. Shown when an unauthenticated
|
|
@@ -1227,23 +1223,17 @@ function EmptyState({
|
|
|
1227
1223
|
}) {
|
|
1228
1224
|
const t = useT();
|
|
1229
1225
|
return (
|
|
1230
|
-
<div className="flex flex-col items-center justify-center
|
|
1231
|
-
<
|
|
1232
|
-
<IconStack2 className="w-7 h-7 text-[#609FF8]" />
|
|
1233
|
-
</div>
|
|
1234
|
-
<h2 className="text-xl font-semibold text-foreground mb-2">
|
|
1226
|
+
<div className="flex min-h-[60vh] flex-col items-center justify-center gap-5 text-center">
|
|
1227
|
+
<h2 className="text-xl font-semibold text-foreground">
|
|
1235
1228
|
{t("home.emptyTitle")}
|
|
1236
1229
|
</h2>
|
|
1237
|
-
<p className="text-sm text-muted-foreground max-w-sm mb-8 leading-relaxed">
|
|
1238
|
-
{t("home.emptyDescription")}
|
|
1239
|
-
</p>
|
|
1240
1230
|
<Button
|
|
1241
1231
|
onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
|
|
1242
1232
|
onCreateDeck(e as React.MouseEvent<HTMLElement>)
|
|
1243
1233
|
}
|
|
1244
1234
|
>
|
|
1245
|
-
<IconPlus className="
|
|
1246
|
-
{t("home.
|
|
1235
|
+
<IconPlus className="size-4" />
|
|
1236
|
+
{t("home.createFirstDeck")}
|
|
1247
1237
|
</Button>
|
|
1248
1238
|
</div>
|
|
1249
1239
|
);
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
CommandMenu,
|
|
17
17
|
useCommandMenuShortcut,
|
|
18
18
|
} from "@agent-native/core/client/navigation";
|
|
19
|
+
import { registerFirstRunOnboardingExtension } from "@agent-native/core/client/onboarding";
|
|
19
20
|
import { getThemeInitScript } from "@agent-native/core/client/ui";
|
|
20
21
|
import { IconHierarchy2, IconSun, IconMoon } from "@tabler/icons-react";
|
|
21
22
|
import { useQueryClient } from "@tanstack/react-query";
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
import type { LinksFunction } from "react-router";
|
|
34
35
|
|
|
35
36
|
import { Layout as AppLayout } from "@/components/layout/Layout";
|
|
37
|
+
import { FirstDeckOnboardingFlow } from "@/components/onboarding/FirstDeckOnboardingFlow";
|
|
36
38
|
import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
|
|
37
39
|
import { DeckProvider } from "@/context/DeckContext";
|
|
38
40
|
import { useNavigationState } from "@/hooks/use-navigation-state";
|
|
@@ -42,6 +44,12 @@ import changelog from "../CHANGELOG.md?raw";
|
|
|
42
44
|
import { i18nCatalog } from "./i18n";
|
|
43
45
|
|
|
44
46
|
import stylesheet from "./global.css?url";
|
|
47
|
+
|
|
48
|
+
registerFirstRunOnboardingExtension({
|
|
49
|
+
id: "slides-first-deck",
|
|
50
|
+
component: FirstDeckOnboardingFlow,
|
|
51
|
+
});
|
|
52
|
+
|
|
45
53
|
configureTracking({
|
|
46
54
|
getDefaultProps: (_name, properties) => ({
|
|
47
55
|
...properties,
|
|
@@ -21,6 +21,7 @@ import { and, eq } from "drizzle-orm";
|
|
|
21
21
|
import { getDeckUrl } from "../../actions/_app-url.js";
|
|
22
22
|
import { SLIDES_USER_PREFS_KEY } from "../../shared/slides-user-prefs.js";
|
|
23
23
|
import { getDb, schema } from "../db/index.js";
|
|
24
|
+
import { SLIDES_DECK_COMMENT_EMAIL_ID } from "./emails.js";
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* `deck-missing` stays distinct from `no-recipients`: one means the deck could
|
|
@@ -99,6 +100,41 @@ async function threadParticipants(
|
|
|
99
100
|
return rows.map((row) => row.authorEmail);
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
export function renderDeckCommentEmail({
|
|
104
|
+
actor,
|
|
105
|
+
title,
|
|
106
|
+
url,
|
|
107
|
+
content,
|
|
108
|
+
isReply,
|
|
109
|
+
}: {
|
|
110
|
+
actor: string;
|
|
111
|
+
title: string;
|
|
112
|
+
url: string;
|
|
113
|
+
content: string;
|
|
114
|
+
isReply: boolean;
|
|
115
|
+
}) {
|
|
116
|
+
return {
|
|
117
|
+
subject: isReply
|
|
118
|
+
? `${actor} replied to a comment on "${title}"`
|
|
119
|
+
: `${actor} commented on "${title}"`,
|
|
120
|
+
...renderEmail({
|
|
121
|
+
preheader: isReply
|
|
122
|
+
? `${actor} replied to a comment on ${title}.`
|
|
123
|
+
: `${actor} commented on ${title}.`,
|
|
124
|
+
heading: isReply ? "New reply on your deck" : "New comment",
|
|
125
|
+
paragraphs: [
|
|
126
|
+
isReply
|
|
127
|
+
? `${emailStrong(actor)} replied in a comment thread on ${emailStrong(title)}.`
|
|
128
|
+
: `${emailStrong(actor)} commented on ${emailStrong(title)}.`,
|
|
129
|
+
`"${excerpt(content)}"`,
|
|
130
|
+
],
|
|
131
|
+
cta: { label: "Open deck", url },
|
|
132
|
+
footer:
|
|
133
|
+
"You received this because you own or participated in this thread. Turn these off in Slides settings.",
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
102
138
|
export async function notifyDeckComment(input: {
|
|
103
139
|
deckId: string;
|
|
104
140
|
slideId: string;
|
|
@@ -153,29 +189,16 @@ async function deliverDeckCommentEmails(input: {
|
|
|
153
189
|
preferenceKey: SLIDES_USER_PREFS_KEY,
|
|
154
190
|
logLabel: LOG_LABEL,
|
|
155
191
|
send: async (to) => {
|
|
156
|
-
const { html, text } = renderEmail({
|
|
157
|
-
preheader: input.isReply
|
|
158
|
-
? `${actor} replied to a comment on ${deck.title}.`
|
|
159
|
-
: `${actor} commented on ${deck.title}.`,
|
|
160
|
-
heading: input.isReply ? "New reply on your deck" : "New comment",
|
|
161
|
-
paragraphs: [
|
|
162
|
-
input.isReply
|
|
163
|
-
? `${emailStrong(actor)} replied in a comment thread on ${emailStrong(deck.title)}.`
|
|
164
|
-
: `${emailStrong(actor)} commented on ${emailStrong(deck.title)}.`,
|
|
165
|
-
`"${excerpt(input.content)}"`,
|
|
166
|
-
],
|
|
167
|
-
cta: { label: "Open deck", url },
|
|
168
|
-
footer:
|
|
169
|
-
"You received this because you own or participated in this thread. Turn these off in Slides settings.",
|
|
170
|
-
});
|
|
171
|
-
|
|
172
192
|
await sendEmail({
|
|
193
|
+
...renderDeckCommentEmail({
|
|
194
|
+
actor,
|
|
195
|
+
title: deck.title,
|
|
196
|
+
url,
|
|
197
|
+
content: input.content,
|
|
198
|
+
isReply: input.isReply,
|
|
199
|
+
}),
|
|
173
200
|
to,
|
|
174
|
-
|
|
175
|
-
? `${actor} replied to a comment on "${deck.title}"`
|
|
176
|
-
: `${actor} commented on "${deck.title}"`,
|
|
177
|
-
html,
|
|
178
|
-
text,
|
|
201
|
+
templateId: SLIDES_DECK_COMMENT_EMAIL_ID,
|
|
179
202
|
});
|
|
180
203
|
},
|
|
181
204
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catalog entries for the transactional emails Slides sends.
|
|
3
|
+
*
|
|
4
|
+
* Registered from `server/plugins/transactional-emails.ts` so Dispatch can list
|
|
5
|
+
* and preview them without the app having sent anything yet.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { defineTransactionalEmail } from "@agent-native/core/email-catalog";
|
|
9
|
+
|
|
10
|
+
import { renderDeckCommentEmail } from "./comment-notifications.js";
|
|
11
|
+
|
|
12
|
+
export const SLIDES_DECK_COMMENT_EMAIL_ID = "slides.deck-comment";
|
|
13
|
+
|
|
14
|
+
let registered = false;
|
|
15
|
+
|
|
16
|
+
export function registerSlidesEmails(): void {
|
|
17
|
+
if (registered) return;
|
|
18
|
+
registered = true;
|
|
19
|
+
|
|
20
|
+
defineTransactionalEmail({
|
|
21
|
+
id: SLIDES_DECK_COMMENT_EMAIL_ID,
|
|
22
|
+
name: "Deck comment",
|
|
23
|
+
trigger:
|
|
24
|
+
"Someone posts a comment or a thread reply on a slide. Subject and copy differ slightly for a reply; both send under this id.",
|
|
25
|
+
recipientLabel: "Deck owner and authors",
|
|
26
|
+
recipient:
|
|
27
|
+
"The deck owner, plus every prior author in the thread when the new comment is a reply. The list is re-checked against the deck's live ACL and filtered by each user's `emailNotifications` preference; the comment's own author never receives it.",
|
|
28
|
+
senderLabel: "Default sender",
|
|
29
|
+
sender:
|
|
30
|
+
"The configured default sender. This call site sets no `from`, `fromName`, `replyTo`, or `appSender`.",
|
|
31
|
+
preview: () =>
|
|
32
|
+
renderDeckCommentEmail({
|
|
33
|
+
actor: "Sam Rivera",
|
|
34
|
+
title: "Series A narrative",
|
|
35
|
+
url: "https://example.com/decks/deck_sample?slide=3",
|
|
36
|
+
content: "Slide 3 needs the updated revenue chart before Thursday.",
|
|
37
|
+
isReply: false,
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -16,5 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export * from "./types.js";
|
|
18
18
|
export * from "./brand-signals.js";
|
|
19
|
+
export * from "./tokens.js";
|
|
19
20
|
export { extractDesignTokensFromUrl, validateUrl, parseOwnerRepo, fetchGitHubJson, fetchGitHubJsonResult, fetchGitHubRaw, parseTailwindConfig, parseCss, detectStylingFramework, createCodeAnalysisState, analyzeCodeFile, analyzeCssFile, analyzeTailwindConfig, analyzeJsonTheme, analyzePackageJson, analyzeThemeSourceFile, addFont, extractCssVars, extractCodeColors, extractCodeFonts, extractDocumentColors, extractDocumentFonts, classifyFile, suggestionsForType, unique, MAX_FILES, MAX_FILE_SIZE, FETCH_TIMEOUT, ROOT_PATTERNS, SECONDARY_PATHS, CODE_MAX_FILES, CODE_MAX_TOTAL_BYTES, } from "../server/design-token-utils.js";
|
|
20
21
|
export type { ContentType, ParsedCss, ParsedTailwindConfig, CodeAnalysisState, UrlExtractionResult, GitHubFetchOptions, GitHubJsonResult, } from "../server/design-token-utils.js";
|
package/dist/brand-kit/index.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export * from "./types.js";
|
|
18
18
|
export * from "./brand-signals.js";
|
|
19
|
+
export * from "./tokens.js";
|
|
19
20
|
// Import-source parsing + token extraction (Tailwind/CSS/GitHub/URL/document/
|
|
20
21
|
// code analysis). These already power the import-* actions across templates.
|
|
21
22
|
export {
|