@agent-native/core 0.153.10 → 0.154.1
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.md +20 -30
- package/corpus/templates/analytics/actions/search-dashboard-references.ts +58 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/analytics/app/lib/utils.ts +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewSqlPopover.tsx +1 -1
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +366 -3
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +3 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +6 -2
- package/corpus/templates/calendar/app/components/calendar/EventDialog.tsx +1 -1
- package/corpus/templates/calendar/app/lib/utils.ts +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +32 -5
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +15 -15
- package/corpus/templates/clips/app/i18n/en-US.ts +3 -3
- package/corpus/templates/clips/app/lib/utils.ts +5 -6
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +43 -8
- package/corpus/templates/clips/desktop/src/app.tsx +26 -12
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +23 -9
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +261 -11
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +21 -3
- package/corpus/templates/clips/shared/mic-audio-cleanup.ts +350 -0
- package/corpus/templates/content/actions/resolve-content-landing.ts +162 -32
- package/corpus/templates/content/app/i18n-data.ts +10 -10
- package/corpus/templates/content/scripts/check-native-deps.mjs +181 -15
- package/corpus/templates/content/shared/content-landing.ts +5 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +79 -7
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +14 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +2 -2
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +35 -11
- package/corpus/templates/design/actions/get-design-system.ts +103 -3
- package/corpus/templates/design/actions/import-design-tokens.ts +37 -8
- package/corpus/templates/design/actions/import-github.ts +32 -138
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +49 -16
- package/corpus/templates/design/actions/present-design-variants.ts +93 -4
- package/corpus/templates/design/actions/run-design-audit.ts +229 -0
- package/corpus/templates/design/actions/sync-design-system-with-builder.ts +64 -0
- package/corpus/templates/design/app/components/design/code-workbench/commands.ts +2 -2
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +17 -4
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +5 -1
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +5 -1
- package/corpus/templates/design/app/hooks/use-question-flow.ts +81 -5
- package/corpus/templates/design/app/i18n/en-US.ts +1 -1
- package/corpus/templates/design/app/i18n-data.ts +32 -1
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +10 -10
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +83 -11
- package/corpus/templates/design/app/pages/DesignSystems.tsx +14 -0
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +22 -0
- package/corpus/templates/design/changelog/2026-08-13-a-screen-that-would-render-behind-an-invisible-alpine-overla.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-attach-a-ui-screenshot-and-the-design-is-reproduced-not-rein.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-linking-a-design-system-means-you-never-get-generic-directio.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-reports-when-a-screen-ignores-its-linke.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-the-design-system-preview-now-shows-how-many-named-tokens-we.md +6 -0
- package/corpus/templates/design/changelog/2026-08-13-your-design-system-prompt-and-reference-screenshots-now-reac.md +6 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +18 -2
- package/corpus/templates/design/shared/design-review.ts +1 -0
- package/corpus/templates/design/shared/html-integrity.ts +171 -0
- package/corpus/templates/mail/app/lib/utils.ts +1 -1
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +10 -6
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +41 -3
- package/corpus/templates/slides/actions/patch-deck.ts +12 -3
- package/corpus/templates/slides/actions/sync-design-system-with-builder.ts +64 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +1 -1
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +193 -20
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +73 -1
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +64 -34
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +34 -41
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +119 -91
- package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +16 -0
- package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +15 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +158 -31
- package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +30 -14
- package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +2 -2
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +4 -1
- package/corpus/templates/slides/app/components/editor/rich-text-selection.ts +14 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +24 -0
- package/corpus/templates/slides/app/context/DeckContext.tsx +19 -31
- package/corpus/templates/slides/app/global.css +24 -0
- package/corpus/templates/slides/app/hooks/use-navigation-state.ts +20 -17
- package/corpus/templates/slides/app/i18n/en-US.ts +19 -10
- package/corpus/templates/slides/app/lib/deck-filter.ts +47 -0
- package/corpus/templates/slides/app/lib/export-google-slides-client.ts +15 -4
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +637 -1
- package/corpus/templates/slides/app/lib/image-download.ts +84 -0
- package/corpus/templates/slides/app/lib/utils.ts +1 -1
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +9 -0
- package/corpus/templates/slides/app/pages/Index.tsx +25 -9
- package/corpus/templates/slides/changelog/2026-08-13-clicking-a-slide-thumbnail-now-focuses-it-so-the-slide-shortc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-duplicating-or-restoring-a-slide-now-keeps-its-transition-ani.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-opening-presentation-mode-from-the-agent-now-starts-on-the-re.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-13-slide-transitions-can-be-set-from-a-visible-control-in-the-sl.md +6 -0
- package/corpus/templates/slides/netlify.toml +1 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +14 -2
- package/dist/a2a/audience.d.ts +2 -0
- package/dist/a2a/audience.js +23 -0
- package/dist/a2a/client.d.ts +4 -0
- package/dist/a2a/client.js +32 -14
- package/dist/a2a/server.d.ts +9 -4
- package/dist/a2a/server.js +52 -25
- package/dist/a2a/types.d.ts +4 -4
- package/dist/agent/production-agent.js +1 -1
- package/dist/brand-kit/types.d.ts +10 -2
- package/dist/cli/code.js +1 -1
- package/dist/cli/index.js +30 -1
- package/dist/cli/native-dependencies.d.ts +24 -0
- package/dist/cli/native-dependencies.js +264 -0
- package/dist/cli/plan-local.js +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +2 -2
- package/dist/cli/visualize-repo.js +1 -1
- package/dist/client/FeedbackButton.js +12 -12
- package/dist/client/agent-chat-adapter.js +3 -4
- package/dist/client/assistant-ui-recovery.d.ts +1 -1
- package/dist/client/assistant-ui-recovery.js +4 -0
- package/dist/client/chat/message-components.d.ts +11 -3
- package/dist/client/chat/message-components.js +31 -5
- package/dist/client/chat/tool-call-display.d.ts +2 -1
- package/dist/client/chat/tool-call-display.js +33 -15
- package/dist/client/db-admin/SqlEditor.js +1 -1
- package/dist/client/dev-overlay/DevOverlay.js +2 -2
- package/dist/client/extensions/portable-extension.js +4 -0
- package/dist/client/guided-questions.d.ts +8 -0
- package/dist/client/guided-questions.js +12 -3
- package/dist/client/sharing/ShareButton.js +16 -24
- package/dist/client/sse-event-processor.js +35 -15
- package/dist/client/tool-display.d.ts +9 -0
- package/dist/client/tool-display.js +39 -0
- package/dist/client/vite-dev-recovery-script.js +1 -1
- 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/extensions/html-shell.js +5 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
- package/dist/server/agent-capabilities.js +0 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -13
- package/dist/server/agent-chat/action-filters-a2a.js +59 -23
- package/dist/server/agent-chat/prompt-resources.js +17 -16
- package/dist/server/agent-chat-plugin.d.ts +9 -0
- package/dist/server/agent-chat-plugin.js +29 -7
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/builder-design-systems.d.ts +33 -1
- package/dist/server/builder-design-systems.js +293 -11
- package/dist/server/design-token-utils.d.ts +11 -0
- package/dist/server/design-token-utils.js +68 -16
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +2 -2
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
IconCheck,
|
|
20
20
|
IconExternalLink,
|
|
21
21
|
IconChevronDown,
|
|
22
|
+
IconRefresh,
|
|
22
23
|
} from "@tabler/icons-react";
|
|
23
24
|
import { useState, useCallback, useEffect, useRef, useMemo } from "react";
|
|
24
25
|
import { toast } from "sonner";
|
|
@@ -59,6 +60,8 @@ interface DesignSystemSetupProps {
|
|
|
59
60
|
interface GitHubLink {
|
|
60
61
|
id: string;
|
|
61
62
|
url: string;
|
|
63
|
+
ref?: string;
|
|
64
|
+
include?: string[];
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
interface UploadedFile {
|
|
@@ -81,6 +84,13 @@ interface BuilderSourceDetails {
|
|
|
81
84
|
tokenValues?: Record<string, string>;
|
|
82
85
|
docCount?: number;
|
|
83
86
|
warning?: string;
|
|
87
|
+
githubSources?: Array<{
|
|
88
|
+
repoUrl: string;
|
|
89
|
+
ref?: string;
|
|
90
|
+
include?: string[];
|
|
91
|
+
exclude?: string[];
|
|
92
|
+
}>;
|
|
93
|
+
syncedAt?: string;
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
interface ExistingDesignSystem {
|
|
@@ -91,6 +101,25 @@ interface ExistingDesignSystem {
|
|
|
91
101
|
builder?: BuilderSourceDetails | null;
|
|
92
102
|
}
|
|
93
103
|
|
|
104
|
+
interface BuilderIndexInput {
|
|
105
|
+
projectName?: string;
|
|
106
|
+
description?: string;
|
|
107
|
+
githubSources?: Array<{
|
|
108
|
+
repoUrl: string;
|
|
109
|
+
ref?: string;
|
|
110
|
+
include?: string[];
|
|
111
|
+
exclude?: string[];
|
|
112
|
+
}>;
|
|
113
|
+
githubRepoUrl?: string;
|
|
114
|
+
codeFiles?: Array<{
|
|
115
|
+
filename: string;
|
|
116
|
+
content: string;
|
|
117
|
+
mimeType?: string;
|
|
118
|
+
encoding?: "utf8" | "base64";
|
|
119
|
+
}>;
|
|
120
|
+
designMd?: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
94
123
|
type OtherSource = "brand" | "code" | "files" | "existing" | "context";
|
|
95
124
|
|
|
96
125
|
function normalizeWebsiteUrlInput(input: string): string | null {
|
|
@@ -134,6 +163,8 @@ export function DesignSystemSetup({
|
|
|
134
163
|
const [websiteUrl, setWebsiteUrl] = useState("");
|
|
135
164
|
const [websiteUrls, setWebsiteUrls] = useState<string[]>([]);
|
|
136
165
|
const [githubUrl, setGithubUrl] = useState("");
|
|
166
|
+
const [githubRef, setGithubRef] = useState("");
|
|
167
|
+
const [githubPaths, setGithubPaths] = useState("");
|
|
137
168
|
const [githubLinks, setGithubLinks] = useState<GitHubLink[]>([]);
|
|
138
169
|
const [codeFiles, setCodeFiles] = useState<UploadedFile[]>([]);
|
|
139
170
|
const [docFiles, setDocFiles] = useState<UploadedFile[]>([]);
|
|
@@ -211,6 +242,13 @@ export function DesignSystemSetup({
|
|
|
211
242
|
const imageInputRef = useRef<HTMLInputElement>(null);
|
|
212
243
|
const figInputRef = useRef<HTMLInputElement>(null);
|
|
213
244
|
const updateSystemMutation = useActionMutation("update-design-system");
|
|
245
|
+
const syncSystemMutation = useActionMutation(
|
|
246
|
+
"sync-design-system-with-builder",
|
|
247
|
+
);
|
|
248
|
+
const indexSystemMutation = useActionMutation<
|
|
249
|
+
BuilderIndexResult,
|
|
250
|
+
BuilderIndexInput
|
|
251
|
+
>("index-design-system-with-builder");
|
|
214
252
|
|
|
215
253
|
const {
|
|
216
254
|
data: existingDs,
|
|
@@ -267,6 +305,8 @@ export function DesignSystemSetup({
|
|
|
267
305
|
setWebsiteUrl("");
|
|
268
306
|
setWebsiteUrls([]);
|
|
269
307
|
setGithubUrl("");
|
|
308
|
+
setGithubRef("");
|
|
309
|
+
setGithubPaths("");
|
|
270
310
|
setGithubLinks([]);
|
|
271
311
|
setCodeFiles([]);
|
|
272
312
|
setDocFiles([]);
|
|
@@ -323,9 +363,23 @@ export function DesignSystemSetup({
|
|
|
323
363
|
const addGithubLink = useCallback(() => {
|
|
324
364
|
const url = githubUrl.trim();
|
|
325
365
|
if (!url) return;
|
|
326
|
-
|
|
366
|
+
const include = githubPaths
|
|
367
|
+
.split(/[\n,]/)
|
|
368
|
+
.map((path) => path.trim().replace(/^\/+|\/+$/g, ""))
|
|
369
|
+
.filter(Boolean);
|
|
370
|
+
setGithubLinks((prev) => [
|
|
371
|
+
...prev,
|
|
372
|
+
{
|
|
373
|
+
id: crypto.randomUUID(),
|
|
374
|
+
url,
|
|
375
|
+
...(githubRef.trim() ? { ref: githubRef.trim() } : {}),
|
|
376
|
+
...(include.length > 0 ? { include: [...new Set(include)] } : {}),
|
|
377
|
+
},
|
|
378
|
+
]);
|
|
327
379
|
setGithubUrl("");
|
|
328
|
-
|
|
380
|
+
setGithubRef("");
|
|
381
|
+
setGithubPaths("");
|
|
382
|
+
}, [githubPaths, githubRef, githubUrl]);
|
|
329
383
|
|
|
330
384
|
const readTextFiles = useCallback(
|
|
331
385
|
(
|
|
@@ -432,12 +486,66 @@ export function DesignSystemSetup({
|
|
|
432
486
|
}
|
|
433
487
|
};
|
|
434
488
|
|
|
489
|
+
const handleSync = useCallback(async () => {
|
|
490
|
+
if (!editingId || !existingDs?.builder?.githubSources?.length) return;
|
|
491
|
+
setGenerating(true);
|
|
492
|
+
try {
|
|
493
|
+
await syncSystemMutation.mutateAsync({ id: editingId });
|
|
494
|
+
toast.success(t("designSystemSetup.syncStarted"));
|
|
495
|
+
} catch (error) {
|
|
496
|
+
toast.error(t("designSystemSetup.syncFailed"), {
|
|
497
|
+
description:
|
|
498
|
+
error instanceof Error
|
|
499
|
+
? error.message
|
|
500
|
+
: t("designSystemSetup.syncFailed"),
|
|
501
|
+
});
|
|
502
|
+
} finally {
|
|
503
|
+
setGenerating(false);
|
|
504
|
+
}
|
|
505
|
+
}, [editingId, existingDs, syncSystemMutation, t]);
|
|
506
|
+
|
|
435
507
|
const handleGenerate = useCallback(async () => {
|
|
436
508
|
if (editingId) {
|
|
437
509
|
await handleEditSave();
|
|
438
510
|
return;
|
|
439
511
|
}
|
|
440
512
|
|
|
513
|
+
const isGithubOnlySource =
|
|
514
|
+
githubLinks.length > 0 &&
|
|
515
|
+
websiteUrls.length === 0 &&
|
|
516
|
+
codeFiles.length === 0 &&
|
|
517
|
+
!builderIndexResult &&
|
|
518
|
+
docFiles.length === 0 &&
|
|
519
|
+
imageFiles.length === 0 &&
|
|
520
|
+
!selectedSystemId &&
|
|
521
|
+
!brandNotes.trim() &&
|
|
522
|
+
!customInstructions.trim();
|
|
523
|
+
if (isGithubOnlySource) {
|
|
524
|
+
setGenerating(true);
|
|
525
|
+
try {
|
|
526
|
+
await indexSystemMutation.mutateAsync({
|
|
527
|
+
projectName: companyName.trim() || undefined,
|
|
528
|
+
githubSources: githubLinks.map((link) => ({
|
|
529
|
+
repoUrl: link.url,
|
|
530
|
+
...(link.ref ? { ref: link.ref } : {}),
|
|
531
|
+
...(link.include?.length ? { include: link.include } : {}),
|
|
532
|
+
})),
|
|
533
|
+
});
|
|
534
|
+
toast.success(t("designSystemSetup.generationStarted"));
|
|
535
|
+
onComplete();
|
|
536
|
+
} catch (error) {
|
|
537
|
+
toast.error(t("designSystemSetup.updateFailed"), {
|
|
538
|
+
description:
|
|
539
|
+
error instanceof Error
|
|
540
|
+
? error.message
|
|
541
|
+
: t("designSystemSetup.updateFailed"),
|
|
542
|
+
});
|
|
543
|
+
} finally {
|
|
544
|
+
setGenerating(false);
|
|
545
|
+
}
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
|
|
441
549
|
const requestedTitle = companyName.trim();
|
|
442
550
|
const localDesignSystemId = builderIndexResult?.localDesignSystemId;
|
|
443
551
|
if (requestedTitle && localDesignSystemId) {
|
|
@@ -485,7 +593,15 @@ export function DesignSystemSetup({
|
|
|
485
593
|
|
|
486
594
|
if (githubLinks.length > 0) {
|
|
487
595
|
parts.push(
|
|
488
|
-
`\n## Connect Code: GitHub Repositories\
|
|
596
|
+
`\n## Connect Code: GitHub Repositories\nMake one call to \`index-design-system-with-builder\` with \`githubSources\` set to this JSON array:\n\n\`\`\`json\n${JSON.stringify(
|
|
597
|
+
githubLinks.map((link) => ({
|
|
598
|
+
repoUrl: link.url,
|
|
599
|
+
...(link.ref ? { ref: link.ref } : {}),
|
|
600
|
+
...(link.include?.length ? { include: link.include } : {}),
|
|
601
|
+
})),
|
|
602
|
+
null,
|
|
603
|
+
2,
|
|
604
|
+
)}\n\`\`\`\n\nBuilder is the source of truth for repo/code design-system indexing. The action creates one local selectable proxy design system for Slides flows. If Builder is not connected, stop and tell me to connect Builder (free tier available) from Settings.`,
|
|
489
605
|
);
|
|
490
606
|
}
|
|
491
607
|
|
|
@@ -610,6 +726,7 @@ export function DesignSystemSetup({
|
|
|
610
726
|
onComplete,
|
|
611
727
|
t,
|
|
612
728
|
updateSystemMutation,
|
|
729
|
+
indexSystemMutation,
|
|
613
730
|
existingDs,
|
|
614
731
|
]);
|
|
615
732
|
|
|
@@ -651,7 +768,16 @@ export function DesignSystemSetup({
|
|
|
651
768
|
</div>
|
|
652
769
|
|
|
653
770
|
{editingId && existingDs?.builder ? (
|
|
654
|
-
<BuilderSourceStatus
|
|
771
|
+
<BuilderSourceStatus
|
|
772
|
+
builder={existingDs.builder}
|
|
773
|
+
onSync={
|
|
774
|
+
existingDs.builder.githubSources?.length &&
|
|
775
|
+
existingDs.builder.sourceKind !== "mixed"
|
|
776
|
+
? handleSync
|
|
777
|
+
: undefined
|
|
778
|
+
}
|
|
779
|
+
syncing={syncSystemMutation.isPending}
|
|
780
|
+
/>
|
|
655
781
|
) : null}
|
|
656
782
|
|
|
657
783
|
{!editingId && (
|
|
@@ -895,8 +1021,28 @@ export function DesignSystemSetup({
|
|
|
895
1021
|
{t("designSystemSetup.add")}
|
|
896
1022
|
</Button>
|
|
897
1023
|
</div>
|
|
1024
|
+
<div className="grid gap-2 sm:grid-cols-2">
|
|
1025
|
+
<Input
|
|
1026
|
+
value={githubRef}
|
|
1027
|
+
onChange={(e) => setGithubRef(e.target.value)}
|
|
1028
|
+
placeholder={t("designSystemSetup.githubRef")}
|
|
1029
|
+
aria-label={t("designSystemSetup.githubRef")}
|
|
1030
|
+
className="bg-accent border-border text-foreground placeholder:text-muted-foreground"
|
|
1031
|
+
/>
|
|
1032
|
+
<Input
|
|
1033
|
+
value={githubPaths}
|
|
1034
|
+
onChange={(e) => setGithubPaths(e.target.value)}
|
|
1035
|
+
placeholder={t("designSystemSetup.githubPaths")}
|
|
1036
|
+
aria-label={t("designSystemSetup.githubPaths")}
|
|
1037
|
+
className="bg-accent border-border text-foreground placeholder:text-muted-foreground"
|
|
1038
|
+
/>
|
|
1039
|
+
</div>
|
|
898
1040
|
<TagList
|
|
899
|
-
items={githubLinks.map((l) =>
|
|
1041
|
+
items={githubLinks.map((l) =>
|
|
1042
|
+
[l.url, l.ref, l.include?.join(", ")]
|
|
1043
|
+
.filter(Boolean)
|
|
1044
|
+
.join(" · "),
|
|
1045
|
+
)}
|
|
900
1046
|
onRemove={(i) =>
|
|
901
1047
|
setGithubLinks((p) => p.filter((_, j) => j !== i))
|
|
902
1048
|
}
|
|
@@ -1253,7 +1399,15 @@ function SourceAccordionRow({
|
|
|
1253
1399
|
);
|
|
1254
1400
|
}
|
|
1255
1401
|
|
|
1256
|
-
function BuilderSourceStatus({
|
|
1402
|
+
function BuilderSourceStatus({
|
|
1403
|
+
builder,
|
|
1404
|
+
onSync,
|
|
1405
|
+
syncing = false,
|
|
1406
|
+
}: {
|
|
1407
|
+
builder: BuilderSourceDetails;
|
|
1408
|
+
onSync?: () => void;
|
|
1409
|
+
syncing?: boolean;
|
|
1410
|
+
}) {
|
|
1257
1411
|
const t = useT();
|
|
1258
1412
|
const docs = builder.docCount ?? builder.docs?.length ?? 0;
|
|
1259
1413
|
const tokens = Object.keys(builder.tokenValues ?? {}).length;
|
|
@@ -1357,20 +1511,39 @@ function BuilderSourceStatus({ builder }: { builder: BuilderSourceDetails }) {
|
|
|
1357
1511
|
{statusTitle}
|
|
1358
1512
|
</div>
|
|
1359
1513
|
</div>
|
|
1360
|
-
{builder.builderUrl ? (
|
|
1361
|
-
<div className="mt-3 border-t border-border pt-3">
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1514
|
+
{builder.builderUrl || onSync ? (
|
|
1515
|
+
<div className="mt-3 flex flex-wrap items-center gap-3 border-t border-border pt-3">
|
|
1516
|
+
{builder.builderUrl ? (
|
|
1517
|
+
<a
|
|
1518
|
+
href={withBuilderUtmTrackingParams(builder.builderUrl, {
|
|
1519
|
+
campaign: "product",
|
|
1520
|
+
content: "design_system_intelligence",
|
|
1521
|
+
})}
|
|
1522
|
+
target="_blank"
|
|
1523
|
+
rel="noreferrer"
|
|
1524
|
+
className="inline-flex items-center gap-1.5 text-xs font-medium text-foreground underline-offset-4 hover:underline"
|
|
1525
|
+
>
|
|
1526
|
+
{t("designSystemSetup.sourceOpenInBuilder")}
|
|
1527
|
+
<IconExternalLink className="size-3.5" />
|
|
1528
|
+
</a>
|
|
1529
|
+
) : null}
|
|
1530
|
+
{onSync ? (
|
|
1531
|
+
<Button
|
|
1532
|
+
type="button"
|
|
1533
|
+
variant="ghost"
|
|
1534
|
+
size="sm"
|
|
1535
|
+
onClick={onSync}
|
|
1536
|
+
disabled={syncing}
|
|
1537
|
+
className="h-7 gap-1.5 px-2 text-xs"
|
|
1538
|
+
>
|
|
1539
|
+
<IconRefresh
|
|
1540
|
+
className={cn("size-3.5", syncing && "animate-spin")}
|
|
1541
|
+
/>
|
|
1542
|
+
{syncing
|
|
1543
|
+
? t("designSystemSetup.syncingSource")
|
|
1544
|
+
: t("designSystemSetup.syncSource")}
|
|
1545
|
+
</Button>
|
|
1546
|
+
) : null}
|
|
1374
1547
|
</div>
|
|
1375
1548
|
) : null}
|
|
1376
1549
|
</section>
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IconLoader2,
|
|
4
|
+
IconPlus,
|
|
5
|
+
IconTextSize,
|
|
6
|
+
IconTransitionRight,
|
|
7
|
+
} from "@tabler/icons-react";
|
|
3
8
|
import { useEffect, useRef, useState } from "react";
|
|
4
9
|
|
|
10
|
+
import {
|
|
11
|
+
DropdownMenu,
|
|
12
|
+
DropdownMenuContent,
|
|
13
|
+
DropdownMenuItem,
|
|
14
|
+
DropdownMenuTrigger,
|
|
15
|
+
} from "@/components/ui/dropdown-menu";
|
|
5
16
|
import {
|
|
6
17
|
Tooltip,
|
|
7
18
|
TooltipContent,
|
|
8
19
|
TooltipTrigger,
|
|
9
20
|
} from "@/components/ui/tooltip";
|
|
21
|
+
import type { Slide } from "@/context/DeckContext";
|
|
10
22
|
import { useAgentGenerating } from "@/hooks/use-agent-generating";
|
|
11
23
|
import { cn } from "@/lib/utils";
|
|
12
24
|
|
|
@@ -19,6 +31,15 @@ const IDLE_CLASS =
|
|
|
19
31
|
const ACTIVE_CLASS = "bg-accent text-foreground";
|
|
20
32
|
const DIVIDER_CLASS = "mx-1 h-4 w-px shrink-0 bg-border";
|
|
21
33
|
|
|
34
|
+
type SlideTransition = NonNullable<Slide["transition"]>;
|
|
35
|
+
|
|
36
|
+
const TRANSITIONS: { value: SlideTransition; labelKey: string }[] = [
|
|
37
|
+
{ value: "instant", labelKey: "editorToolbar.transition_instant" },
|
|
38
|
+
{ value: "fade", labelKey: "editorToolbar.transition_fade" },
|
|
39
|
+
{ value: "slide", labelKey: "editorToolbar.transition_slide" },
|
|
40
|
+
{ value: "zoom", labelKey: "editorToolbar.transition_zoom" },
|
|
41
|
+
];
|
|
42
|
+
|
|
22
43
|
/**
|
|
23
44
|
* Add slide, undo, redo, and add-text-box — the actions that stay put
|
|
24
45
|
* regardless of what is selected. Rendered at the head of the contextual
|
|
@@ -36,6 +57,8 @@ export function EditorActionCluster({
|
|
|
36
57
|
onDuplicateCurrentSlide,
|
|
37
58
|
textBoxMode,
|
|
38
59
|
onToggleTextBoxMode,
|
|
60
|
+
slideTransition,
|
|
61
|
+
onChangeSlideTransition,
|
|
39
62
|
className,
|
|
40
63
|
}: {
|
|
41
64
|
deckId: string;
|
|
@@ -49,12 +72,19 @@ export function EditorActionCluster({
|
|
|
49
72
|
onDuplicateCurrentSlide?: () => void;
|
|
50
73
|
textBoxMode?: boolean;
|
|
51
74
|
onToggleTextBoxMode?: () => void;
|
|
75
|
+
slideTransition?: Slide["transition"];
|
|
76
|
+
onChangeSlideTransition?: (transition: SlideTransition) => void;
|
|
52
77
|
className?: string;
|
|
53
78
|
}) {
|
|
54
79
|
const t = useT();
|
|
55
80
|
const { generating, submit: agentSubmit } = useAgentGenerating();
|
|
56
81
|
const [addSlideOpen, setAddSlideOpen] = useState(false);
|
|
57
82
|
const addSlideRef = useRef<HTMLButtonElement>(null);
|
|
83
|
+
// "none" is a legacy alias the presentation view already treats as instant.
|
|
84
|
+
const activeTransition: SlideTransition =
|
|
85
|
+
!slideTransition || slideTransition === "none"
|
|
86
|
+
? "instant"
|
|
87
|
+
: slideTransition;
|
|
58
88
|
|
|
59
89
|
useEffect(() => {
|
|
60
90
|
if (!generating) onAddSlideGeneratingChange?.(false);
|
|
@@ -125,6 +155,48 @@ export function EditorActionCluster({
|
|
|
125
155
|
</Tooltip>
|
|
126
156
|
</>
|
|
127
157
|
)}
|
|
158
|
+
|
|
159
|
+
{onChangeSlideTransition && currentSlideId && (
|
|
160
|
+
<>
|
|
161
|
+
<div className={DIVIDER_CLASS} />
|
|
162
|
+
<DropdownMenu>
|
|
163
|
+
<Tooltip>
|
|
164
|
+
<TooltipTrigger asChild>
|
|
165
|
+
<DropdownMenuTrigger asChild>
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
aria-label={t("editorToolbar.transition")}
|
|
169
|
+
className={cn(
|
|
170
|
+
BUTTON_CLASS,
|
|
171
|
+
activeTransition === "instant"
|
|
172
|
+
? IDLE_CLASS
|
|
173
|
+
: ACTIVE_CLASS,
|
|
174
|
+
)}
|
|
175
|
+
>
|
|
176
|
+
<IconTransitionRight className="size-4" />
|
|
177
|
+
</button>
|
|
178
|
+
</DropdownMenuTrigger>
|
|
179
|
+
</TooltipTrigger>
|
|
180
|
+
<TooltipContent>{t("editorToolbar.transition")}</TooltipContent>
|
|
181
|
+
</Tooltip>
|
|
182
|
+
<DropdownMenuContent align="start" className="w-40">
|
|
183
|
+
{TRANSITIONS.map((transition) => (
|
|
184
|
+
<DropdownMenuItem
|
|
185
|
+
key={transition.value}
|
|
186
|
+
onSelect={() => onChangeSlideTransition(transition.value)}
|
|
187
|
+
className={
|
|
188
|
+
activeTransition === transition.value
|
|
189
|
+
? "bg-accent text-accent-foreground"
|
|
190
|
+
: undefined
|
|
191
|
+
}
|
|
192
|
+
>
|
|
193
|
+
{t(transition.labelKey)}
|
|
194
|
+
</DropdownMenuItem>
|
|
195
|
+
))}
|
|
196
|
+
</DropdownMenuContent>
|
|
197
|
+
</DropdownMenu>
|
|
198
|
+
</>
|
|
199
|
+
)}
|
|
128
200
|
</div>
|
|
129
201
|
);
|
|
130
202
|
}
|
|
@@ -17,8 +17,7 @@ import {
|
|
|
17
17
|
import { CSS } from "@dnd-kit/utilities";
|
|
18
18
|
import { appStateKeyForBrowserTab } from "@shared/app-state-tabs";
|
|
19
19
|
import { hashSlideContent, type DeckFitState } from "@shared/slide-fit";
|
|
20
|
-
import {
|
|
21
|
-
import { useCallback } from "react";
|
|
20
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
22
21
|
|
|
23
22
|
import SlideRenderer from "@/components/deck/SlideRenderer";
|
|
24
23
|
import type { SlideOverflowInfo } from "@/components/deck/SlideRenderer";
|
|
@@ -34,6 +33,7 @@ import { getAspectRatioDims, type AspectRatio } from "@/lib/aspect-ratios";
|
|
|
34
33
|
import { TAB_ID } from "@/lib/tab-id";
|
|
35
34
|
|
|
36
35
|
import type { DesignSystemData } from "../../../shared/api";
|
|
36
|
+
import { isSlideTextEditingTarget } from "./slide-text-targets";
|
|
37
37
|
|
|
38
38
|
interface EditorSidebarProps {
|
|
39
39
|
slides: Slide[];
|
|
@@ -198,7 +198,12 @@ function SortableSlideThumb({
|
|
|
198
198
|
type="button"
|
|
199
199
|
{...(readOnly ? {} : attributes)}
|
|
200
200
|
{...(readOnly ? {} : listeners)}
|
|
201
|
-
onClick={
|
|
201
|
+
onClick={(event) => {
|
|
202
|
+
// Safari does not focus a button on click, and the slide copy/paste
|
|
203
|
+
// and delete shortcuts are scoped to a focused thumbnail.
|
|
204
|
+
event.currentTarget.focus();
|
|
205
|
+
onSelect();
|
|
206
|
+
}}
|
|
202
207
|
onFocus={onSelect}
|
|
203
208
|
aria-label={t("editorSidebar.selectSlide", { number: index + 1 })}
|
|
204
209
|
aria-current={isActive ? "true" : undefined}
|
|
@@ -317,6 +322,7 @@ export default function EditorSidebar({
|
|
|
317
322
|
generatingSlideSelected = false,
|
|
318
323
|
onSelectGeneratingSlide,
|
|
319
324
|
}: EditorSidebarProps) {
|
|
325
|
+
const [thumbnailListScrolled, setThumbnailListScrolled] = useState(false);
|
|
320
326
|
const slideButtonRefs = useRef(new Map<string, HTMLButtonElement>());
|
|
321
327
|
const measurementsRef = useRef(
|
|
322
328
|
new Map<
|
|
@@ -391,6 +397,10 @@ export default function EditorSidebar({
|
|
|
391
397
|
measurementsRef.current.clear();
|
|
392
398
|
}, [deckId, aspectRatio]);
|
|
393
399
|
|
|
400
|
+
useEffect(() => {
|
|
401
|
+
setThumbnailListScrolled(false);
|
|
402
|
+
}, [deckId]);
|
|
403
|
+
|
|
394
404
|
useEffect(() => {
|
|
395
405
|
return () => {
|
|
396
406
|
if (writeTimerRef.current) clearTimeout(writeTimerRef.current);
|
|
@@ -419,12 +429,20 @@ export default function EditorSidebar({
|
|
|
419
429
|
useEffect(() => {
|
|
420
430
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
421
431
|
if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
|
|
422
|
-
//
|
|
432
|
+
// Text editing and selected canvas objects own arrow keys. The marker
|
|
433
|
+
// query also covers a transient focus loss after a native selection.
|
|
423
434
|
const tag = (e.target as HTMLElement)?.tagName;
|
|
424
435
|
if (
|
|
425
436
|
tag === "INPUT" ||
|
|
426
437
|
tag === "TEXTAREA" ||
|
|
427
|
-
(
|
|
438
|
+
isSlideTextEditingTarget(
|
|
439
|
+
e.target,
|
|
440
|
+
document.activeElement,
|
|
441
|
+
document.querySelector(
|
|
442
|
+
'[contenteditable="true"], [data-editing-block="true"]',
|
|
443
|
+
),
|
|
444
|
+
) ||
|
|
445
|
+
document.querySelector('[data-slide-element-selected="true"]')
|
|
428
446
|
)
|
|
429
447
|
return;
|
|
430
448
|
|
|
@@ -454,39 +472,51 @@ export default function EditorSidebar({
|
|
|
454
472
|
|
|
455
473
|
return (
|
|
456
474
|
<div className="flex h-full min-h-0 w-48 flex-shrink-0 flex-col bg-background sm:w-52">
|
|
457
|
-
<div
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
475
|
+
<div
|
|
476
|
+
className="relative min-h-0 flex-1"
|
|
477
|
+
data-slides-thumbnail-scroll={
|
|
478
|
+
thumbnailListScrolled ? "scrolled" : "top"
|
|
479
|
+
}
|
|
480
|
+
>
|
|
481
|
+
<div
|
|
482
|
+
className="h-full min-h-0 space-y-1 overflow-y-auto overscroll-contain p-2"
|
|
483
|
+
onScroll={(event) => {
|
|
484
|
+
setThumbnailListScrolled(event.currentTarget.scrollTop > 1);
|
|
485
|
+
}}
|
|
461
486
|
>
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
487
|
+
<SortableContext
|
|
488
|
+
items={slides.map((s) => s.id)}
|
|
489
|
+
strategy={verticalListSortingStrategy}
|
|
490
|
+
>
|
|
491
|
+
{slides.map((slide, index) => (
|
|
492
|
+
<SortableSlideThumb
|
|
493
|
+
key={slide.id}
|
|
494
|
+
slide={slide}
|
|
495
|
+
index={index}
|
|
496
|
+
isActive={slide.id === activeSlideId}
|
|
497
|
+
onSelect={() => onSelectSlide(slide.id)}
|
|
498
|
+
readOnly={readOnly}
|
|
499
|
+
registerButtonRef={registerSlideButton}
|
|
500
|
+
presenceUsers={slidePresence?.get(slide.id) ?? []}
|
|
501
|
+
aspectRatio={aspectRatio}
|
|
502
|
+
designSystem={designSystem}
|
|
503
|
+
aiEditing={aiEditedSlideIds.has(slide.id)}
|
|
504
|
+
onOverflowChange={(info) =>
|
|
505
|
+
handleSlideOverflowChange(slide, info)
|
|
506
|
+
}
|
|
507
|
+
/>
|
|
508
|
+
))}
|
|
509
|
+
</SortableContext>
|
|
510
|
+
{generatingSlide && (
|
|
511
|
+
<GeneratingSlideSkeleton
|
|
512
|
+
index={generatingSlide.index}
|
|
472
513
|
aspectRatio={aspectRatio}
|
|
473
514
|
designSystem={designSystem}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
handleSlideOverflowChange(slide, info)
|
|
477
|
-
}
|
|
515
|
+
selected={generatingSlideSelected}
|
|
516
|
+
onSelect={onSelectGeneratingSlide}
|
|
478
517
|
/>
|
|
479
|
-
)
|
|
480
|
-
</
|
|
481
|
-
{generatingSlide && (
|
|
482
|
-
<GeneratingSlideSkeleton
|
|
483
|
-
index={generatingSlide.index}
|
|
484
|
-
aspectRatio={aspectRatio}
|
|
485
|
-
designSystem={designSystem}
|
|
486
|
-
selected={generatingSlideSelected}
|
|
487
|
-
onSelect={onSelectGeneratingSlide}
|
|
488
|
-
/>
|
|
489
|
-
)}
|
|
518
|
+
)}
|
|
519
|
+
</div>
|
|
490
520
|
</div>
|
|
491
521
|
</div>
|
|
492
522
|
);
|