@agent-native/core 0.153.9 → 0.154.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/DataSources.tsx +2 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/ViewSqlPopover.tsx +1 -1
- package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +4 -2
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -2
- 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/app/root.tsx +4 -1
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +2 -2
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +43 -8
- package/corpus/templates/clips/desktop/src/app.tsx +27 -13
- 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/app/i18n-data.ts +10 -10
- package/corpus/templates/content/scripts/check-native-deps.mjs +181 -15
- 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/DesignImportPanel.tsx +2 -1
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
- 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/plan/app/pages/PlansPage.tsx +5 -2
- 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/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/EditorSidebar.tsx +58 -33
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +28 -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/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/global.css +24 -0
- package/corpus/templates/slides/app/hooks/use-navigation-state.ts +5 -1
- 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/Index.tsx +25 -9
- package/corpus/templates/slides/netlify.toml +1 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +14 -2
- 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/skills-content/help.d.ts +1 -1
- package/dist/cli/skills-content/help.js +2 -1
- package/dist/cli/skills.js +2 -1
- package/dist/cli/visualize-repo.js +1 -1
- package/dist/client/FeedbackButton.js +12 -12
- package/dist/client/NewWorkspaceAppFlow.js +4 -1
- package/dist/client/agent-chat-adapter.js +3 -4
- package/dist/client/agent-page/AgentTabsPage.d.ts +2 -2
- package/dist/client/agent-page/AgentTabsPage.js +12 -9
- 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/ExtensionsSidebarSection.js +2 -1
- 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/onboarding/FirstRunOnboarding.js +2 -1
- package/dist/client/org/TeamPage.js +14 -3
- package/dist/client/settings/SettingsPanel.js +26 -1
- 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/extensions/html-shell.js +5 -0
- package/dist/integrations/catalog.js +9 -8
- package/dist/observability/routes.d.ts +2 -2
- package/dist/secrets/routes.d.ts +6 -6
- 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 +31 -9
- 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/dist/server/onboarding-html.js +2 -1
- package/dist/shared/docs-url.d.ts +24 -0
- package/dist/shared/docs-url.js +39 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/templates/default/app/routes/_index.tsx +2 -1
- package/package.json +2 -2
- package/src/templates/default/app/routes/_index.tsx +2 -1
|
@@ -32,6 +32,30 @@ const codeFileSchema = z.object({
|
|
|
32
32
|
),
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
const githubSourceSchema = z.object({
|
|
36
|
+
repoUrl: z.string().trim().min(1).describe("GitHub repository URL"),
|
|
37
|
+
ref: z
|
|
38
|
+
.string()
|
|
39
|
+
.trim()
|
|
40
|
+
.min(1)
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Optional branch, tag, or commit"),
|
|
43
|
+
include: z
|
|
44
|
+
.array(z.string().trim().min(1))
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Optional repository-relative files or folders to include"),
|
|
47
|
+
exclude: z
|
|
48
|
+
.array(z.string().trim().min(1))
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Optional repository-relative files or folders to exclude"),
|
|
51
|
+
instructions: z
|
|
52
|
+
.string()
|
|
53
|
+
.trim()
|
|
54
|
+
.min(1)
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("Optional indexing guidance for this repository"),
|
|
57
|
+
});
|
|
58
|
+
|
|
35
59
|
export default defineAction({
|
|
36
60
|
description:
|
|
37
61
|
"Start Builder DSI design-system indexing from connected code, a GitHub repository, code/design files, and optional design.md guidance. " +
|
|
@@ -49,7 +73,15 @@ export default defineAction({
|
|
|
49
73
|
githubRepoUrl: z
|
|
50
74
|
.string()
|
|
51
75
|
.optional()
|
|
52
|
-
.describe("GitHub repository URL to index with Builder"),
|
|
76
|
+
.describe("Legacy single GitHub repository URL to index with Builder"),
|
|
77
|
+
githubSources: z
|
|
78
|
+
.array(githubSourceSchema)
|
|
79
|
+
.min(1)
|
|
80
|
+
.max(20)
|
|
81
|
+
.optional()
|
|
82
|
+
.describe(
|
|
83
|
+
"GitHub repositories to index in one design system. Each source may specify a branch/tag/commit and repository-relative files or folders.",
|
|
84
|
+
),
|
|
53
85
|
connectedProjectId: z
|
|
54
86
|
.string()
|
|
55
87
|
.optional()
|
|
@@ -69,6 +101,7 @@ export default defineAction({
|
|
|
69
101
|
projectName,
|
|
70
102
|
description,
|
|
71
103
|
githubRepoUrl,
|
|
104
|
+
githubSources,
|
|
72
105
|
connectedProjectId,
|
|
73
106
|
codeFiles,
|
|
74
107
|
designMd,
|
|
@@ -81,6 +114,7 @@ export default defineAction({
|
|
|
81
114
|
projectName,
|
|
82
115
|
description,
|
|
83
116
|
githubRepoUrl,
|
|
117
|
+
githubRepos: githubSources,
|
|
84
118
|
connectedProjectId,
|
|
85
119
|
files,
|
|
86
120
|
});
|
|
@@ -93,10 +127,13 @@ export default defineAction({
|
|
|
93
127
|
orgId: getRequestOrgId(),
|
|
94
128
|
projectName,
|
|
95
129
|
description,
|
|
130
|
+
githubSources:
|
|
131
|
+
githubSources ?? (githubRepoUrl ? [{ repoUrl: githubRepoUrl }] : []),
|
|
96
132
|
sourceKind:
|
|
97
|
-
|
|
133
|
+
(githubSources?.length || githubRepoUrl) &&
|
|
134
|
+
(codeFiles?.length || designMd)
|
|
98
135
|
? "mixed"
|
|
99
|
-
: githubRepoUrl
|
|
136
|
+
: githubSources?.length || githubRepoUrl
|
|
100
137
|
? "github"
|
|
101
138
|
: codeFiles?.length || designMd
|
|
102
139
|
? "code"
|
|
@@ -107,6 +144,7 @@ export default defineAction({
|
|
|
107
144
|
...result,
|
|
108
145
|
...proxy,
|
|
109
146
|
uploadedFileCount: files.length,
|
|
147
|
+
githubSourceCount: githubSources?.length ?? (githubRepoUrl ? 1 : 0),
|
|
110
148
|
};
|
|
111
149
|
},
|
|
112
150
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineAction } from "@agent-native/core";
|
|
2
|
+
import {
|
|
3
|
+
parseBuilderDesignSystemProxyReference,
|
|
4
|
+
startBuilderDesignSystemIndex,
|
|
5
|
+
} from "@agent-native/core/server";
|
|
6
|
+
import { getRequestUserEmail } from "@agent-native/core/server/request-context";
|
|
7
|
+
import { assertAccess, resolveAccess } from "@agent-native/core/sharing";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
10
|
+
import "../server/db/index.js";
|
|
11
|
+
import { upsertBuilderProxyDesignSystem } from "../server/lib/builder-design-system-proxy.js";
|
|
12
|
+
|
|
13
|
+
export default defineAction({
|
|
14
|
+
description:
|
|
15
|
+
"Re-index a Builder-backed GitHub design system using its persisted repository, ref, and file/folder scope. Requires editor access.",
|
|
16
|
+
schema: z.object({
|
|
17
|
+
id: z.string().min(1).describe("Local design system id"),
|
|
18
|
+
}),
|
|
19
|
+
run: async ({ id }) => {
|
|
20
|
+
await assertAccess("design-system", id, "editor");
|
|
21
|
+
const access = await resolveAccess("design-system", id);
|
|
22
|
+
if (!access) throw new Error("Design system not found");
|
|
23
|
+
|
|
24
|
+
const reference = parseBuilderDesignSystemProxyReference(
|
|
25
|
+
access.resource.data,
|
|
26
|
+
);
|
|
27
|
+
if (!reference?.githubSources?.length) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
"This design system has no persisted GitHub source scope to sync.",
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
if (reference.sourceKind === "mixed") {
|
|
33
|
+
throw new Error(
|
|
34
|
+
"This design system combines GitHub with non-replayable sources. Re-import all sources before syncing it.",
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const result = await startBuilderDesignSystemIndex({
|
|
39
|
+
projectName: access.resource.title,
|
|
40
|
+
description: access.resource.description ?? undefined,
|
|
41
|
+
githubRepos: reference.githubSources,
|
|
42
|
+
});
|
|
43
|
+
const ownerEmail = getRequestUserEmail();
|
|
44
|
+
if (!ownerEmail) throw new Error("no authenticated user");
|
|
45
|
+
|
|
46
|
+
const proxy = await upsertBuilderProxyDesignSystem({
|
|
47
|
+
result,
|
|
48
|
+
ownerEmail: access.resource.ownerEmail,
|
|
49
|
+
orgId: access.resource.orgId,
|
|
50
|
+
projectName: access.resource.title,
|
|
51
|
+
description: access.resource.description ?? undefined,
|
|
52
|
+
sourceKind: reference.sourceKind,
|
|
53
|
+
githubSources: reference.githubSources,
|
|
54
|
+
localDesignSystemId: id,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...result,
|
|
59
|
+
...proxy,
|
|
60
|
+
synced: true,
|
|
61
|
+
githubSourceCount: reference.githubSources.length,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
});
|
|
@@ -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>
|
|
@@ -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[];
|
|
@@ -317,6 +317,7 @@ export default function EditorSidebar({
|
|
|
317
317
|
generatingSlideSelected = false,
|
|
318
318
|
onSelectGeneratingSlide,
|
|
319
319
|
}: EditorSidebarProps) {
|
|
320
|
+
const [thumbnailListScrolled, setThumbnailListScrolled] = useState(false);
|
|
320
321
|
const slideButtonRefs = useRef(new Map<string, HTMLButtonElement>());
|
|
321
322
|
const measurementsRef = useRef(
|
|
322
323
|
new Map<
|
|
@@ -391,6 +392,10 @@ export default function EditorSidebar({
|
|
|
391
392
|
measurementsRef.current.clear();
|
|
392
393
|
}, [deckId, aspectRatio]);
|
|
393
394
|
|
|
395
|
+
useEffect(() => {
|
|
396
|
+
setThumbnailListScrolled(false);
|
|
397
|
+
}, [deckId]);
|
|
398
|
+
|
|
394
399
|
useEffect(() => {
|
|
395
400
|
return () => {
|
|
396
401
|
if (writeTimerRef.current) clearTimeout(writeTimerRef.current);
|
|
@@ -419,12 +424,20 @@ export default function EditorSidebar({
|
|
|
419
424
|
useEffect(() => {
|
|
420
425
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
421
426
|
if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
|
|
422
|
-
//
|
|
427
|
+
// Text editing and selected canvas objects own arrow keys. The marker
|
|
428
|
+
// query also covers a transient focus loss after a native selection.
|
|
423
429
|
const tag = (e.target as HTMLElement)?.tagName;
|
|
424
430
|
if (
|
|
425
431
|
tag === "INPUT" ||
|
|
426
432
|
tag === "TEXTAREA" ||
|
|
427
|
-
(
|
|
433
|
+
isSlideTextEditingTarget(
|
|
434
|
+
e.target,
|
|
435
|
+
document.activeElement,
|
|
436
|
+
document.querySelector(
|
|
437
|
+
'[contenteditable="true"], [data-editing-block="true"]',
|
|
438
|
+
),
|
|
439
|
+
) ||
|
|
440
|
+
document.querySelector('[data-slide-element-selected="true"]')
|
|
428
441
|
)
|
|
429
442
|
return;
|
|
430
443
|
|
|
@@ -454,39 +467,51 @@ export default function EditorSidebar({
|
|
|
454
467
|
|
|
455
468
|
return (
|
|
456
469
|
<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
|
-
|
|
470
|
+
<div
|
|
471
|
+
className="relative min-h-0 flex-1"
|
|
472
|
+
data-slides-thumbnail-scroll={
|
|
473
|
+
thumbnailListScrolled ? "scrolled" : "top"
|
|
474
|
+
}
|
|
475
|
+
>
|
|
476
|
+
<div
|
|
477
|
+
className="h-full min-h-0 space-y-1 overflow-y-auto overscroll-contain p-2"
|
|
478
|
+
onScroll={(event) => {
|
|
479
|
+
setThumbnailListScrolled(event.currentTarget.scrollTop > 1);
|
|
480
|
+
}}
|
|
461
481
|
>
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
482
|
+
<SortableContext
|
|
483
|
+
items={slides.map((s) => s.id)}
|
|
484
|
+
strategy={verticalListSortingStrategy}
|
|
485
|
+
>
|
|
486
|
+
{slides.map((slide, index) => (
|
|
487
|
+
<SortableSlideThumb
|
|
488
|
+
key={slide.id}
|
|
489
|
+
slide={slide}
|
|
490
|
+
index={index}
|
|
491
|
+
isActive={slide.id === activeSlideId}
|
|
492
|
+
onSelect={() => onSelectSlide(slide.id)}
|
|
493
|
+
readOnly={readOnly}
|
|
494
|
+
registerButtonRef={registerSlideButton}
|
|
495
|
+
presenceUsers={slidePresence?.get(slide.id) ?? []}
|
|
496
|
+
aspectRatio={aspectRatio}
|
|
497
|
+
designSystem={designSystem}
|
|
498
|
+
aiEditing={aiEditedSlideIds.has(slide.id)}
|
|
499
|
+
onOverflowChange={(info) =>
|
|
500
|
+
handleSlideOverflowChange(slide, info)
|
|
501
|
+
}
|
|
502
|
+
/>
|
|
503
|
+
))}
|
|
504
|
+
</SortableContext>
|
|
505
|
+
{generatingSlide && (
|
|
506
|
+
<GeneratingSlideSkeleton
|
|
507
|
+
index={generatingSlide.index}
|
|
472
508
|
aspectRatio={aspectRatio}
|
|
473
509
|
designSystem={designSystem}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
handleSlideOverflowChange(slide, info)
|
|
477
|
-
}
|
|
510
|
+
selected={generatingSlideSelected}
|
|
511
|
+
onSelect={onSelectGeneratingSlide}
|
|
478
512
|
/>
|
|
479
|
-
)
|
|
480
|
-
</
|
|
481
|
-
{generatingSlide && (
|
|
482
|
-
<GeneratingSlideSkeleton
|
|
483
|
-
index={generatingSlide.index}
|
|
484
|
-
aspectRatio={aspectRatio}
|
|
485
|
-
designSystem={designSystem}
|
|
486
|
-
selected={generatingSlideSelected}
|
|
487
|
-
onSelect={onSelectGeneratingSlide}
|
|
488
|
-
/>
|
|
489
|
-
)}
|
|
513
|
+
)}
|
|
514
|
+
</div>
|
|
490
515
|
</div>
|
|
491
516
|
</div>
|
|
492
517
|
);
|