@agent-native/core 0.153.10 → 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/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/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/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/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/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/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- 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/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 +3 -3
|
@@ -71,7 +71,10 @@ function readFileAsDataUrl(file: File): Promise<string> {
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
// guard:allow-raw-color — fixed light checkerboard tile keeps transparency visible.
|
|
75
|
+
const CHECKER_A = "#e5e5e5";
|
|
76
|
+
// guard:allow-raw-color — fixed light checkerboard tile keeps transparency visible.
|
|
77
|
+
const CHECKER_B = "#f5f5f5";
|
|
75
78
|
const CHECKERBOARD_IMAGE = `linear-gradient(45deg, ${CHECKER_A} 25%, transparent 25%), linear-gradient(-45deg, ${CHECKER_A} 25%, transparent 25%), linear-gradient(45deg, transparent 75%, ${CHECKER_A} 75%), linear-gradient(-45deg, transparent 75%, ${CHECKER_A} 75%)`;
|
|
76
79
|
const FIT_MARKER_RE =
|
|
77
80
|
/\/\*\s*agent-native-image-fit:(fill|fit|crop|tile)\s*\*\//i;
|
|
@@ -345,6 +348,7 @@ export function ImageFillControls({
|
|
|
345
348
|
backgroundImage: value.url
|
|
346
349
|
? `url("${escapeForQuotedUrl(value.url.trim())}")`
|
|
347
350
|
: CHECKERBOARD_IMAGE,
|
|
351
|
+
backgroundColor: value.url ? undefined : CHECKER_B,
|
|
348
352
|
backgroundSize: value.url
|
|
349
353
|
? value.fit === "fit"
|
|
350
354
|
? "contain"
|
|
@@ -7,6 +7,7 @@ import { type PromptComposerSubmitOptions } from "@agent-native/core/client/comp
|
|
|
7
7
|
import { useCallback } from "react";
|
|
8
8
|
|
|
9
9
|
import { sendToDesignAgentChat } from "@/lib/agent-chat";
|
|
10
|
+
import { loadDesignSystemGenerationContext } from "@/pages/design-editor/generation-prompt-directives";
|
|
10
11
|
|
|
11
12
|
export interface QuestionFlowModelSelection {
|
|
12
13
|
model?: string;
|
|
@@ -14,6 +15,23 @@ export interface QuestionFlowModelSelection {
|
|
|
14
15
|
effort?: PromptComposerSubmitOptions["effort"];
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* What the user actually supplied at kickoff. The intake turn is forced to emit
|
|
20
|
+
* only a questionnaire and then stop, so THIS continuation is the turn that
|
|
21
|
+
* writes HTML — and a fresh thread inherits nothing. Re-sending the brief here
|
|
22
|
+
* is the only thing that puts the user's own prompt, reference screenshots, and
|
|
23
|
+
* design system in front of the model at the moment it generates.
|
|
24
|
+
*/
|
|
25
|
+
export interface QuestionFlowGenerationBrief {
|
|
26
|
+
/** The user's original words, replayed verbatim — never a paraphrase. */
|
|
27
|
+
prompt?: string;
|
|
28
|
+
designSystemId?: string | null;
|
|
29
|
+
/** Data URLs; re-attached so the reference screenshot survives the hop. */
|
|
30
|
+
images?: string[];
|
|
31
|
+
/** Extracted text from uploaded files (specs, outlines, token dumps). */
|
|
32
|
+
uploadedFileContext?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
interface UseQuestionFlowOptions {
|
|
18
36
|
enabled?: boolean;
|
|
19
37
|
continuationTabId?: string | null;
|
|
@@ -25,12 +43,49 @@ interface UseQuestionFlowOptions {
|
|
|
25
43
|
* filled after render, so a snapshot taken here would be the pre-kickoff one.
|
|
26
44
|
*/
|
|
27
45
|
getModelSelection?: () => QuestionFlowModelSelection | null | undefined;
|
|
46
|
+
/** Read at send time, for the same reason as `getModelSelection`. */
|
|
47
|
+
getGenerationBrief?: () => QuestionFlowGenerationBrief | null | undefined;
|
|
28
48
|
}
|
|
29
49
|
|
|
30
50
|
function designQuestionsStateKey(designId: string | undefined): string {
|
|
31
51
|
return designId ? `show-questions:${designId}` : "show-questions";
|
|
32
52
|
}
|
|
33
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Render the kickoff brief as prompt context for the continuation turn.
|
|
56
|
+
* Exported and pure so the carry-through is testable without a DOM — this is
|
|
57
|
+
* the whole fix for "the agent ignored my design system / screenshot / brief".
|
|
58
|
+
*/
|
|
59
|
+
export function buildGenerationBriefContext(
|
|
60
|
+
brief: QuestionFlowGenerationBrief | null | undefined,
|
|
61
|
+
designSystemContext: string,
|
|
62
|
+
): string {
|
|
63
|
+
return [
|
|
64
|
+
brief?.prompt?.trim()
|
|
65
|
+
? [
|
|
66
|
+
"## The user's original request (verbatim)",
|
|
67
|
+
"This is the spec for what to build. The answers below refine it;",
|
|
68
|
+
"they do not replace it. Do not restate it as a looser paraphrase.",
|
|
69
|
+
"",
|
|
70
|
+
brief.prompt.trim(),
|
|
71
|
+
].join("\n")
|
|
72
|
+
: "",
|
|
73
|
+
brief?.images?.length
|
|
74
|
+
? [
|
|
75
|
+
`## ${brief.images.length} reference image(s) re-attached to this message`,
|
|
76
|
+
"Treat an attached UI screenshot as a layout specification to",
|
|
77
|
+
"reproduce — its structure, hierarchy, density, and component",
|
|
78
|
+
"grammar — not as loose inspiration. Match it unless an answer",
|
|
79
|
+
"below explicitly overrides a part of it.",
|
|
80
|
+
].join("\n")
|
|
81
|
+
: "",
|
|
82
|
+
brief?.uploadedFileContext?.trim() ?? "",
|
|
83
|
+
designSystemContext,
|
|
84
|
+
]
|
|
85
|
+
.filter(Boolean)
|
|
86
|
+
.join("\n\n");
|
|
87
|
+
}
|
|
88
|
+
|
|
34
89
|
const RESPONSIVE_GENERATION_REQUIREMENTS =
|
|
35
90
|
'Responsive behavior is mandatory for every web design. Read the form-factor answer above: for Desktop or Both/responsive, call generate-design with `primaryViewport: "desktop"` and a 1440x1024 canvas frame; use `primaryViewport: "mobile"` only for an explicitly mobile-primary choice. Use mobile-first responsive CSS, then take desktop and mobile screenshots and fix any overflow before reporting the design complete.';
|
|
36
91
|
|
|
@@ -47,6 +102,7 @@ export function useQuestionFlow(
|
|
|
47
102
|
continuationTabId,
|
|
48
103
|
onContinue,
|
|
49
104
|
getModelSelection,
|
|
105
|
+
getGenerationBrief,
|
|
50
106
|
}: UseQuestionFlowOptions = {},
|
|
51
107
|
) {
|
|
52
108
|
const stateKey = designQuestionsStateKey(designId);
|
|
@@ -79,9 +135,21 @@ export function useQuestionFlow(
|
|
|
79
135
|
});
|
|
80
136
|
|
|
81
137
|
const sendContinuation = useCallback(
|
|
82
|
-
(message: string, context?: string) => {
|
|
138
|
+
async (message: string, context?: string) => {
|
|
83
139
|
const selection = getModelSelection?.() ?? {};
|
|
84
140
|
const { model, engine, effort } = selection;
|
|
141
|
+
const brief = getGenerationBrief?.() ?? null;
|
|
142
|
+
// Re-hydrated rather than snapshotted at kickoff: the user can link or
|
|
143
|
+
// change the design system while the questionnaire is open. This never
|
|
144
|
+
// throws — a load failure returns instruction text telling the agent to
|
|
145
|
+
// stop rather than improvise a generic style.
|
|
146
|
+
const designSystemContext = brief?.designSystemId
|
|
147
|
+
? await loadDesignSystemGenerationContext(brief.designSystemId)
|
|
148
|
+
: "";
|
|
149
|
+
const briefContext = buildGenerationBriefContext(
|
|
150
|
+
brief,
|
|
151
|
+
designSystemContext,
|
|
152
|
+
);
|
|
85
153
|
// Always request `newTab` (mirroring useAgentGenerating.submit's
|
|
86
154
|
// default). Without it, when there is no continuationTabId yet the
|
|
87
155
|
// message goes to whatever tab is currently active, but the id we
|
|
@@ -96,9 +164,10 @@ export function useQuestionFlow(
|
|
|
96
164
|
// real destination thread.
|
|
97
165
|
const tabId = sendToDesignAgentChat({
|
|
98
166
|
message,
|
|
99
|
-
context,
|
|
167
|
+
context: [briefContext, context].filter(Boolean).join("\n\n"),
|
|
100
168
|
submit: true,
|
|
101
169
|
newTab: true,
|
|
170
|
+
...(brief?.images?.length ? { images: brief.images } : {}),
|
|
102
171
|
...(continuationTabId ? { tabId: continuationTabId } : {}),
|
|
103
172
|
...(model ? { model } : {}),
|
|
104
173
|
...(engine ? { engine } : {}),
|
|
@@ -107,7 +176,14 @@ export function useQuestionFlow(
|
|
|
107
176
|
onContinue?.(tabId);
|
|
108
177
|
flow.clear();
|
|
109
178
|
},
|
|
110
|
-
[
|
|
179
|
+
[
|
|
180
|
+
continuationTabId,
|
|
181
|
+
designId,
|
|
182
|
+
flow,
|
|
183
|
+
getGenerationBrief,
|
|
184
|
+
getModelSelection,
|
|
185
|
+
onContinue,
|
|
186
|
+
],
|
|
111
187
|
);
|
|
112
188
|
|
|
113
189
|
const handleSubmit = useCallback(
|
|
@@ -129,13 +205,13 @@ export function useQuestionFlow(
|
|
|
129
205
|
.filter(Boolean)
|
|
130
206
|
.join("\n");
|
|
131
207
|
|
|
132
|
-
sendContinuation("Here are my answers — go ahead.", context);
|
|
208
|
+
void sendContinuation("Here are my answers — go ahead.", context);
|
|
133
209
|
},
|
|
134
210
|
[designId, sendContinuation],
|
|
135
211
|
);
|
|
136
212
|
|
|
137
213
|
const handleSkip = useCallback(() => {
|
|
138
|
-
sendContinuation(
|
|
214
|
+
void sendContinuation(
|
|
139
215
|
"Skip the questions — decide for me.",
|
|
140
216
|
designId
|
|
141
217
|
? `The user skipped the pre-generation questions for design ${designId}. Proceed with reasonable defaults. ${RESPONSIVE_GENERATION_REQUIREMENTS} Generate one polished first direction unless the original prompt explicitly requested options.`
|
|
@@ -25,7 +25,7 @@ const messages = {
|
|
|
25
25
|
commentMode: "Comment",
|
|
26
26
|
sendToAgent: "Send to agent",
|
|
27
27
|
sendingToAgent: "Sending to agent…",
|
|
28
|
-
enterToPost: "Enter to post · Shift
|
|
28
|
+
enterToPost: "Enter to post · Shift Enter for a new line",
|
|
29
29
|
post: "Post",
|
|
30
30
|
posting: "Posting…",
|
|
31
31
|
postFailed: "Could not post this comment",
|
|
@@ -754,7 +754,7 @@ const enUS = {
|
|
|
754
754
|
big: "Big nudge",
|
|
755
755
|
unit: "px",
|
|
756
756
|
description:
|
|
757
|
-
"Arrow keys move by the small amount and Shift
|
|
757
|
+
"Arrow keys move by the small amount and Shift arrow by the big one. Inside an auto layout frame, arrows reorder the layer instead of moving it.",
|
|
758
758
|
},
|
|
759
759
|
keys: {
|
|
760
760
|
or: "or",
|
|
@@ -1487,6 +1487,8 @@ const enUS = {
|
|
|
1487
1487
|
websiteUrl: "Website-URL",
|
|
1488
1488
|
add: "Add",
|
|
1489
1489
|
githubRepository: "GitHub repository",
|
|
1490
|
+
githubRef: "Branch, tag, or commit (optional)",
|
|
1491
|
+
githubPaths: "Files or folders, comma-separated (optional)",
|
|
1490
1492
|
privateRepoPrefix: "Private repos need a fine-grained token saved as",
|
|
1491
1493
|
privateRepoSuffix: "with Contents read access.",
|
|
1492
1494
|
localCodeFiles: "Connect code files",
|
|
@@ -1658,6 +1660,7 @@ const enUS = {
|
|
|
1658
1660
|
logos: "Logos",
|
|
1659
1661
|
assets: "Assets",
|
|
1660
1662
|
savedCount: "{{count}} saved",
|
|
1663
|
+
namedTokens: "Named tokens",
|
|
1661
1664
|
colorLabels: {
|
|
1662
1665
|
primary: "Primary",
|
|
1663
1666
|
secondary: "Secondary",
|
|
@@ -1964,6 +1967,8 @@ const designLocaleOverrides = {
|
|
|
1964
1967
|
websiteUrl: "网站URL",
|
|
1965
1968
|
add: "添加",
|
|
1966
1969
|
githubRepository: "GitHub 存储库",
|
|
1970
|
+
githubRef: "分支、标签或提交(可选)",
|
|
1971
|
+
githubPaths: "文件或文件夹,以逗号分隔(可选)",
|
|
1967
1972
|
privateRepoPrefix: "私人仓库需要一个细粒度的令牌,另存为",
|
|
1968
1973
|
privateRepoSuffix: "具有内容读取权限。",
|
|
1969
1974
|
localCodeFiles: "连接代码文件",
|
|
@@ -2128,6 +2133,7 @@ const designLocaleOverrides = {
|
|
|
2128
2133
|
logos: "标志",
|
|
2129
2134
|
assets: "资产",
|
|
2130
2135
|
savedCount: "已保存 {{count}} 个",
|
|
2136
|
+
namedTokens: "具名代币",
|
|
2131
2137
|
colorLabels: {
|
|
2132
2138
|
primary: "基本的",
|
|
2133
2139
|
secondary: "中学",
|
|
@@ -2379,6 +2385,8 @@ const designLocaleOverrides = {
|
|
|
2379
2385
|
websiteUrl: "Sitio web URL",
|
|
2380
2386
|
add: "Agregar",
|
|
2381
2387
|
githubRepository: "repositorio GitHub",
|
|
2388
|
+
githubRef: "Rama, etiqueta o commit (opcional)",
|
|
2389
|
+
githubPaths: "Archivos o carpetas, separados por comas (opcional)",
|
|
2382
2390
|
privateRepoPrefix:
|
|
2383
2391
|
"Los repositorios privados necesitan un token detallado guardado como",
|
|
2384
2392
|
privateRepoSuffix: "con acceso de lectura de contenidos.",
|
|
@@ -2558,6 +2566,7 @@ const designLocaleOverrides = {
|
|
|
2558
2566
|
logos: "Logotipos",
|
|
2559
2567
|
assets: "Activos",
|
|
2560
2568
|
savedCount: "{{count}} guardado",
|
|
2569
|
+
namedTokens: "Tokens con nombre",
|
|
2561
2570
|
colorLabels: {
|
|
2562
2571
|
primary: "Primario",
|
|
2563
2572
|
secondary: "Secundario",
|
|
@@ -2814,6 +2823,9 @@ const designLocaleOverrides = {
|
|
|
2814
2823
|
websiteUrl: "Site Web URL",
|
|
2815
2824
|
add: "Ajouter",
|
|
2816
2825
|
githubRepository: "référentiel GitHub",
|
|
2826
|
+
githubRef: "Branche, tag ou commit (facultatif)",
|
|
2827
|
+
githubPaths:
|
|
2828
|
+
"Fichiers ou dossiers, séparés par des virgules (facultatif)",
|
|
2817
2829
|
privateRepoPrefix:
|
|
2818
2830
|
"Les dépôts privés nécessitent un jeton à granularité fine enregistré sous",
|
|
2819
2831
|
privateRepoSuffix: "avec accès en lecture au contenu.",
|
|
@@ -2993,6 +3005,7 @@ const designLocaleOverrides = {
|
|
|
2993
3005
|
logos: "Logos",
|
|
2994
3006
|
assets: "Actifs",
|
|
2995
3007
|
savedCount: "{{count}} enregistré",
|
|
3008
|
+
namedTokens: "Jetons nommés",
|
|
2996
3009
|
colorLabels: {
|
|
2997
3010
|
primary: "Primaire",
|
|
2998
3011
|
secondary: "Secondaire",
|
|
@@ -3249,6 +3262,8 @@ const designLocaleOverrides = {
|
|
|
3249
3262
|
websiteUrl: "Website URL",
|
|
3250
3263
|
add: "Hinzufügen",
|
|
3251
3264
|
githubRepository: "GitHub-Repository",
|
|
3265
|
+
githubRef: "Branch, Tag oder Commit (optional)",
|
|
3266
|
+
githubPaths: "Dateien oder Ordner, durch Kommas getrennt (optional)",
|
|
3252
3267
|
privateRepoPrefix:
|
|
3253
3268
|
"Private Repos benötigen einen feinkörnigen Token, der unter gespeichert wird",
|
|
3254
3269
|
privateRepoSuffix: "mit Lesezugriff auf Inhalte.",
|
|
@@ -3429,6 +3444,7 @@ const designLocaleOverrides = {
|
|
|
3429
3444
|
logos: "Logos",
|
|
3430
3445
|
assets: "Vermögenswerte",
|
|
3431
3446
|
savedCount: "{{count}} gespeichert",
|
|
3447
|
+
namedTokens: "Benannte Tokens",
|
|
3432
3448
|
colorLabels: {
|
|
3433
3449
|
primary: "Primär",
|
|
3434
3450
|
secondary: "Sekundär",
|
|
@@ -3684,6 +3700,8 @@ const designLocaleOverrides = {
|
|
|
3684
3700
|
websiteUrl: "ウェブサイト URL",
|
|
3685
3701
|
add: "追加",
|
|
3686
3702
|
githubRepository: "GitHub リポジトリ",
|
|
3703
|
+
githubRef: "ブランチ、タグ、コミット(任意)",
|
|
3704
|
+
githubPaths: "ファイルまたはフォルダー(カンマ区切り、任意)",
|
|
3687
3705
|
privateRepoPrefix:
|
|
3688
3706
|
"プライベート リポジトリには、次のように保存されたきめ細かいトークンが必要です。",
|
|
3689
3707
|
privateRepoSuffix: "コンテンツ読み取りアクセス付き。",
|
|
@@ -3860,6 +3878,7 @@ const designLocaleOverrides = {
|
|
|
3860
3878
|
logos: "ロゴ",
|
|
3861
3879
|
assets: "資産",
|
|
3862
3880
|
savedCount: "{{count}} 保存しました",
|
|
3881
|
+
namedTokens: "名前付きトークン",
|
|
3863
3882
|
colorLabels: {
|
|
3864
3883
|
primary: "主要な",
|
|
3865
3884
|
secondary: "二次",
|
|
@@ -4113,6 +4132,8 @@ const designLocaleOverrides = {
|
|
|
4113
4132
|
websiteUrl: "웹사이트 URL",
|
|
4114
4133
|
add: "추가하다",
|
|
4115
4134
|
githubRepository: "GitHub 저장소",
|
|
4135
|
+
githubRef: "브랜치, 태그 또는 커밋 (선택 사항)",
|
|
4136
|
+
githubPaths: "파일 또는 폴더, 쉼표로 구분 (선택 사항)",
|
|
4116
4137
|
privateRepoPrefix:
|
|
4117
4138
|
"비공개 저장소에는 다음과 같이 저장된 세분화된 토큰이 필요합니다.",
|
|
4118
4139
|
privateRepoSuffix: "콘텐츠 읽기 액세스 권한이 있습니다.",
|
|
@@ -4284,6 +4305,7 @@ const designLocaleOverrides = {
|
|
|
4284
4305
|
logos: "로고",
|
|
4285
4306
|
assets: "자산",
|
|
4286
4307
|
savedCount: "{{count}}가 저장되었습니다.",
|
|
4308
|
+
namedTokens: "이름이 지정된 토큰",
|
|
4287
4309
|
colorLabels: {
|
|
4288
4310
|
primary: "주요한",
|
|
4289
4311
|
secondary: "반성",
|
|
@@ -4538,6 +4560,8 @@ const designLocaleOverrides = {
|
|
|
4538
4560
|
websiteUrl: "Site URL",
|
|
4539
4561
|
add: "Adicionar",
|
|
4540
4562
|
githubRepository: "repositório GitHub",
|
|
4563
|
+
githubRef: "Branch, tag ou commit (opcional)",
|
|
4564
|
+
githubPaths: "Arquivos ou pastas, separados por vírgulas (opcional)",
|
|
4541
4565
|
privateRepoPrefix:
|
|
4542
4566
|
"Os repositórios privados precisam de um token refinado salvo como",
|
|
4543
4567
|
privateRepoSuffix: "com acesso de leitura de conteúdo.",
|
|
@@ -4715,6 +4739,7 @@ const designLocaleOverrides = {
|
|
|
4715
4739
|
logos: "Logotipos",
|
|
4716
4740
|
assets: "Ativos",
|
|
4717
4741
|
savedCount: "{{count}} salvo",
|
|
4742
|
+
namedTokens: "Tokens nomeados",
|
|
4718
4743
|
colorLabels: {
|
|
4719
4744
|
primary: "Primário",
|
|
4720
4745
|
secondary: "Secundário",
|
|
@@ -4967,6 +4992,8 @@ const designLocaleOverrides = {
|
|
|
4967
4992
|
websiteUrl: "वेबसाइट URL",
|
|
4968
4993
|
add: "जोड़ना",
|
|
4969
4994
|
githubRepository: "GitHub रिपॉजिटरी",
|
|
4995
|
+
githubRef: "ब्रांच, टैग या कमिट (वैकल्पिक)",
|
|
4996
|
+
githubPaths: "फ़ाइलें या फ़ोल्डर, कॉमा से अलग (वैकल्पिक)",
|
|
4970
4997
|
privateRepoPrefix:
|
|
4971
4998
|
"निजी रेपो को एक बढ़िया टोकन के रूप में सहेजे जाने की आवश्यकता होती है",
|
|
4972
4999
|
privateRepoSuffix: "सामग्री पढ़ने की पहुंच के साथ।",
|
|
@@ -5137,6 +5164,7 @@ const designLocaleOverrides = {
|
|
|
5137
5164
|
logos: "लोगो",
|
|
5138
5165
|
assets: "संपत्ति",
|
|
5139
5166
|
savedCount: "{{count}} सहेजा गया",
|
|
5167
|
+
namedTokens: "नामित टोकन",
|
|
5140
5168
|
colorLabels: {
|
|
5141
5169
|
primary: "प्राथमिक",
|
|
5142
5170
|
secondary: "माध्यमिक",
|
|
@@ -5387,6 +5415,8 @@ const designLocaleOverrides = {
|
|
|
5387
5415
|
websiteUrl: "موقع URL",
|
|
5388
5416
|
add: "يضيف",
|
|
5389
5417
|
githubRepository: "مستودع GitHub",
|
|
5418
|
+
githubRef: "فرع أو وسم أو التزام (اختياري)",
|
|
5419
|
+
githubPaths: "الملفات أو المجلدات، مفصولة بفواصل (اختياري)",
|
|
5390
5420
|
privateRepoPrefix:
|
|
5391
5421
|
"تحتاج عمليات إعادة الشراء الخاصة إلى رمز مميز محفوظ باسم",
|
|
5392
5422
|
privateRepoSuffix: "مع محتويات الوصول للقراءة.",
|
|
@@ -5558,6 +5588,7 @@ const designLocaleOverrides = {
|
|
|
5558
5588
|
logos: "الشعارات",
|
|
5559
5589
|
assets: "أصول",
|
|
5560
5590
|
savedCount: "تم حفظ {{count}}",
|
|
5591
|
+
namedTokens: "الرموز المميزة المسماة",
|
|
5561
5592
|
colorLabels: {
|
|
5562
5593
|
primary: "أساسي",
|
|
5563
5594
|
secondary: "ثانوي",
|
|
@@ -58,7 +58,7 @@ export const keyboardShortcutLabels = {
|
|
|
58
58
|
nudgeAmountSmall: "小距離",
|
|
59
59
|
nudgeAmountBig: "大距離",
|
|
60
60
|
nudgeAmountDescription:
|
|
61
|
-
"方向鍵以小距離移動,Shift
|
|
61
|
+
"方向鍵以小距離移動,Shift 方向鍵以大距離移動。在自動版面配置框架內,方向鍵改為調整圖層順序。",
|
|
62
62
|
},
|
|
63
63
|
"zh-CN": {
|
|
64
64
|
title: "键盘快捷键",
|
|
@@ -76,7 +76,7 @@ export const keyboardShortcutLabels = {
|
|
|
76
76
|
nudgeAmountSmall: "小距离",
|
|
77
77
|
nudgeAmountBig: "大距离",
|
|
78
78
|
nudgeAmountDescription:
|
|
79
|
-
"方向键以小距离移动,Shift
|
|
79
|
+
"方向键以小距离移动,Shift 方向键以大距离移动。在自动布局框架内,方向键改为调整图层顺序。",
|
|
80
80
|
},
|
|
81
81
|
"es-ES": {
|
|
82
82
|
title: "Atajos de teclado",
|
|
@@ -95,7 +95,7 @@ export const keyboardShortcutLabels = {
|
|
|
95
95
|
nudgeAmountSmall: "Desplazamiento pequeño",
|
|
96
96
|
nudgeAmountBig: "Desplazamiento grande",
|
|
97
97
|
nudgeAmountDescription:
|
|
98
|
-
"Las flechas mueven la cantidad pequeña y Mayús
|
|
98
|
+
"Las flechas mueven la cantidad pequeña y Mayús flecha la grande. Dentro de un marco de autodiseño, las flechas reordenan la capa.",
|
|
99
99
|
},
|
|
100
100
|
"fr-FR": {
|
|
101
101
|
title: "Raccourcis clavier",
|
|
@@ -115,7 +115,7 @@ export const keyboardShortcutLabels = {
|
|
|
115
115
|
nudgeAmountSmall: "Petit déplacement",
|
|
116
116
|
nudgeAmountBig: "Grand déplacement",
|
|
117
117
|
nudgeAmountDescription:
|
|
118
|
-
"Les flèches déplacent de la petite valeur et Maj
|
|
118
|
+
"Les flèches déplacent de la petite valeur et Maj flèche de la grande. Dans un cadre en disposition automatique, les flèches réorganisent le calque.",
|
|
119
119
|
},
|
|
120
120
|
"de-DE": {
|
|
121
121
|
title: "Tastenkürzel",
|
|
@@ -135,7 +135,7 @@ export const keyboardShortcutLabels = {
|
|
|
135
135
|
nudgeAmountSmall: "Kleiner Schritt",
|
|
136
136
|
nudgeAmountBig: "Großer Schritt",
|
|
137
137
|
nudgeAmountDescription:
|
|
138
|
-
"Pfeiltasten verschieben um den kleinen Wert, Umschalt
|
|
138
|
+
"Pfeiltasten verschieben um den kleinen Wert, Umschalt Pfeil um den großen. In einem Auto-Layout-Rahmen ordnen die Pfeiltasten die Ebene neu an.",
|
|
139
139
|
},
|
|
140
140
|
"ja-JP": {
|
|
141
141
|
title: "キーボードショートカット",
|
|
@@ -153,7 +153,7 @@ export const keyboardShortcutLabels = {
|
|
|
153
153
|
nudgeAmountSmall: "小さい移動量",
|
|
154
154
|
nudgeAmountBig: "大きい移動量",
|
|
155
155
|
nudgeAmountDescription:
|
|
156
|
-
"矢印キーは小さい移動量、Shift
|
|
156
|
+
"矢印キーは小さい移動量、Shift 矢印キーは大きい移動量で移動します。オートレイアウトフレーム内では、矢印キーはレイヤーの順序を変更します。",
|
|
157
157
|
},
|
|
158
158
|
"ko-KR": {
|
|
159
159
|
title: "키보드 단축키",
|
|
@@ -171,7 +171,7 @@ export const keyboardShortcutLabels = {
|
|
|
171
171
|
nudgeAmountSmall: "작은 이동",
|
|
172
172
|
nudgeAmountBig: "큰 이동",
|
|
173
173
|
nudgeAmountDescription:
|
|
174
|
-
"화살표 키는 작은 간격으로, Shift
|
|
174
|
+
"화살표 키는 작은 간격으로, Shift 화살표 키는 큰 간격으로 이동합니다. 오토 레이아웃 프레임 안에서는 화살표 키가 레이어 순서를 변경합니다.",
|
|
175
175
|
},
|
|
176
176
|
"pt-BR": {
|
|
177
177
|
title: "Atalhos de teclado",
|
|
@@ -191,7 +191,7 @@ export const keyboardShortcutLabels = {
|
|
|
191
191
|
nudgeAmountSmall: "Deslocamento pequeno",
|
|
192
192
|
nudgeAmountBig: "Deslocamento grande",
|
|
193
193
|
nudgeAmountDescription:
|
|
194
|
-
"As setas movem pela distância pequena e Shift
|
|
194
|
+
"As setas movem pela distância pequena e Shift seta pela grande. Dentro de um frame com layout automático, as setas reordenam a camada.",
|
|
195
195
|
},
|
|
196
196
|
"hi-IN": {
|
|
197
197
|
title: "कीबोर्ड शॉर्टकट",
|
|
@@ -209,7 +209,7 @@ export const keyboardShortcutLabels = {
|
|
|
209
209
|
nudgeAmountSmall: "छोटी नज",
|
|
210
210
|
nudgeAmountBig: "बड़ी नज",
|
|
211
211
|
nudgeAmountDescription:
|
|
212
|
-
"ऐरो कुंजियाँ छोटी दूरी से और Shift
|
|
212
|
+
"ऐरो कुंजियाँ छोटी दूरी से और Shift ऐरो बड़ी दूरी से ले जाती हैं। ऑटो लेआउट फ़्रेम के अंदर ऐरो कुंजियाँ लेयर का क्रम बदलती हैं।",
|
|
213
213
|
},
|
|
214
214
|
"ar-SA": {
|
|
215
215
|
title: "اختصارات لوحة المفاتيح",
|
|
@@ -227,7 +227,7 @@ export const keyboardShortcutLabels = {
|
|
|
227
227
|
nudgeAmountSmall: "إزاحة صغيرة",
|
|
228
228
|
nudgeAmountBig: "إزاحة كبيرة",
|
|
229
229
|
nudgeAmountDescription:
|
|
230
|
-
"تحرّك مفاتيح الأسهم بالمقدار الصغير، وShift
|
|
230
|
+
"تحرّك مفاتيح الأسهم بالمقدار الصغير، وShift سهم بالمقدار الكبير. داخل إطار التخطيط التلقائي، تعيد مفاتيح الأسهم ترتيب الطبقة.",
|
|
231
231
|
},
|
|
232
232
|
} satisfies Record<Exclude<LocaleCode, "en-US">, KeyboardShortcutLabels>;
|
|
233
233
|
|
|
@@ -43,6 +43,8 @@ import { cn } from "@/lib/utils";
|
|
|
43
43
|
interface GitHubLink {
|
|
44
44
|
id: string;
|
|
45
45
|
url: string;
|
|
46
|
+
ref?: string;
|
|
47
|
+
include?: string[];
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
interface UploadedFile {
|
|
@@ -73,6 +75,12 @@ interface BuilderIndexInput {
|
|
|
73
75
|
projectName?: string;
|
|
74
76
|
description?: string;
|
|
75
77
|
githubRepoUrl?: string;
|
|
78
|
+
githubSources?: Array<{
|
|
79
|
+
repoUrl: string;
|
|
80
|
+
ref?: string;
|
|
81
|
+
include?: string[];
|
|
82
|
+
exclude?: string[];
|
|
83
|
+
}>;
|
|
76
84
|
connectedProjectId?: string;
|
|
77
85
|
codeFiles?: Array<{
|
|
78
86
|
filename: string;
|
|
@@ -93,6 +101,8 @@ export default function DesignSystemSetup() {
|
|
|
93
101
|
const [websiteUrl, setWebsiteUrl] = useState("");
|
|
94
102
|
const [websiteUrls, setWebsiteUrls] = useState<string[]>([]);
|
|
95
103
|
const [githubUrl, setGithubUrl] = useState("");
|
|
104
|
+
const [githubRef, setGithubRef] = useState("");
|
|
105
|
+
const [githubPaths, setGithubPaths] = useState("");
|
|
96
106
|
const [githubLinks, setGithubLinks] = useState<GitHubLink[]>([]);
|
|
97
107
|
const [codeFiles, setCodeFiles] = useState<UploadedFile[]>([]);
|
|
98
108
|
const [docFiles, setDocFiles] = useState<UploadedFile[]>([]);
|
|
@@ -308,10 +318,24 @@ export default function DesignSystemSetup() {
|
|
|
308
318
|
setValidationError(t("designSystemSetup.errors.githubUrl"));
|
|
309
319
|
return;
|
|
310
320
|
}
|
|
311
|
-
|
|
321
|
+
const include = githubPaths
|
|
322
|
+
.split(/[\n,]/)
|
|
323
|
+
.map((path) => path.trim().replace(/^\/+|\/+$/g, ""))
|
|
324
|
+
.filter(Boolean);
|
|
325
|
+
setGithubLinks((prev) => [
|
|
326
|
+
...prev,
|
|
327
|
+
{
|
|
328
|
+
id: crypto.randomUUID(),
|
|
329
|
+
url,
|
|
330
|
+
...(githubRef.trim() ? { ref: githubRef.trim() } : {}),
|
|
331
|
+
...(include.length > 0 ? { include: [...new Set(include)] } : {}),
|
|
332
|
+
},
|
|
333
|
+
]);
|
|
312
334
|
setGithubUrl("");
|
|
335
|
+
setGithubRef("");
|
|
336
|
+
setGithubPaths("");
|
|
313
337
|
setValidationError(null);
|
|
314
|
-
}, [githubUrl, t]);
|
|
338
|
+
}, [githubPaths, githubRef, githubUrl, t]);
|
|
315
339
|
|
|
316
340
|
const removeGithubLink = useCallback((id: string) => {
|
|
317
341
|
setGithubLinks((prev) => prev.filter((l) => l.id !== id));
|
|
@@ -441,12 +465,26 @@ export default function DesignSystemSetup() {
|
|
|
441
465
|
const normalizedWebsiteUrls = pendingWebsiteUrl
|
|
442
466
|
? [...websiteUrls, pendingWebsiteUrl]
|
|
443
467
|
: websiteUrls;
|
|
468
|
+
const pendingGithubInclude = githubPaths
|
|
469
|
+
.split(/[\n,]/)
|
|
470
|
+
.map((path) => path.trim().replace(/^\/+|\/+$/g, ""))
|
|
471
|
+
.filter(Boolean);
|
|
444
472
|
const normalizedGithubLinks = pendingGithubUrl
|
|
445
|
-
? [
|
|
473
|
+
? [
|
|
474
|
+
...githubLinks,
|
|
475
|
+
{
|
|
476
|
+
id: "pending",
|
|
477
|
+
url: pendingGithubUrl,
|
|
478
|
+
...(githubRef.trim() ? { ref: githubRef.trim() } : {}),
|
|
479
|
+
...(pendingGithubInclude.length > 0
|
|
480
|
+
? { include: [...new Set(pendingGithubInclude)] }
|
|
481
|
+
: {}),
|
|
482
|
+
},
|
|
483
|
+
]
|
|
446
484
|
: githubLinks;
|
|
447
485
|
|
|
448
|
-
const
|
|
449
|
-
normalizedGithubLinks.length
|
|
486
|
+
const isGithubOnlySource =
|
|
487
|
+
normalizedGithubLinks.length > 0 &&
|
|
450
488
|
normalizedWebsiteUrls.length === 0 &&
|
|
451
489
|
codeFiles.length === 0 &&
|
|
452
490
|
!builderIndexResult &&
|
|
@@ -455,10 +493,7 @@ export default function DesignSystemSetup() {
|
|
|
455
493
|
assets.length === 0 &&
|
|
456
494
|
!selectedProjectId;
|
|
457
495
|
|
|
458
|
-
if (
|
|
459
|
-
const githubRepoUrl = normalizedGithubLinks[0]?.url;
|
|
460
|
-
if (!githubRepoUrl) return;
|
|
461
|
-
|
|
496
|
+
if (isGithubOnlySource) {
|
|
462
497
|
setValidationError(null);
|
|
463
498
|
try {
|
|
464
499
|
await indexSystemMutation.mutateAsync({
|
|
@@ -467,7 +502,11 @@ export default function DesignSystemSetup() {
|
|
|
467
502
|
[notes.trim(), customInstructions.trim()]
|
|
468
503
|
.filter(Boolean)
|
|
469
504
|
.join("\n\n") || undefined,
|
|
470
|
-
|
|
505
|
+
githubSources: normalizedGithubLinks.map((link) => ({
|
|
506
|
+
repoUrl: link.url,
|
|
507
|
+
...(link.ref ? { ref: link.ref } : {}),
|
|
508
|
+
...(link.include?.length ? { include: link.include } : {}),
|
|
509
|
+
})),
|
|
471
510
|
});
|
|
472
511
|
toast.success(t("designSystemSetup.githubIndexStarted"));
|
|
473
512
|
navigate("/design-systems");
|
|
@@ -507,7 +546,15 @@ export default function DesignSystemSetup() {
|
|
|
507
546
|
|
|
508
547
|
if (normalizedGithubLinks.length > 0) {
|
|
509
548
|
parts.push(
|
|
510
|
-
`\n## Connect Code: GitHub Repositories\
|
|
549
|
+
`\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(
|
|
550
|
+
normalizedGithubLinks.map((link) => ({
|
|
551
|
+
repoUrl: link.url,
|
|
552
|
+
...(link.ref ? { ref: link.ref } : {}),
|
|
553
|
+
...(link.include?.length ? { include: link.include } : {}),
|
|
554
|
+
})),
|
|
555
|
+
null,
|
|
556
|
+
2,
|
|
557
|
+
)}\n\`\`\`\n\nBuilder is the source of truth for repo/code design-system indexing. The action creates one local selectable proxy design system for Design flows. If Builder is not connected, stop and tell me to connect Builder (free tier available) from Settings instead of asking me to paste repository credentials into chat.`,
|
|
511
558
|
);
|
|
512
559
|
}
|
|
513
560
|
|
|
@@ -629,6 +676,8 @@ export default function DesignSystemSetup() {
|
|
|
629
676
|
websiteUrl,
|
|
630
677
|
websiteUrls,
|
|
631
678
|
githubUrl,
|
|
679
|
+
githubRef,
|
|
680
|
+
githubPaths,
|
|
632
681
|
githubLinks,
|
|
633
682
|
codeFiles,
|
|
634
683
|
builderIndexResult,
|
|
@@ -935,6 +984,22 @@ export default function DesignSystemSetup() {
|
|
|
935
984
|
{t("designSystemSetup.add")}
|
|
936
985
|
</Button>
|
|
937
986
|
</div>
|
|
987
|
+
<div className="grid gap-2 sm:grid-cols-2">
|
|
988
|
+
<Input
|
|
989
|
+
value={githubRef}
|
|
990
|
+
onChange={(e) => setGithubRef(e.target.value)}
|
|
991
|
+
placeholder={t("designSystemSetup.githubRef")}
|
|
992
|
+
aria-label={t("designSystemSetup.githubRef")}
|
|
993
|
+
className="bg-accent/50 border-border"
|
|
994
|
+
/>
|
|
995
|
+
<Input
|
|
996
|
+
value={githubPaths}
|
|
997
|
+
onChange={(e) => setGithubPaths(e.target.value)}
|
|
998
|
+
placeholder={t("designSystemSetup.githubPaths")}
|
|
999
|
+
aria-label={t("designSystemSetup.githubPaths")}
|
|
1000
|
+
className="bg-accent/50 border-border"
|
|
1001
|
+
/>
|
|
1002
|
+
</div>
|
|
938
1003
|
<p className="mt-2 text-xs text-muted-foreground/80">
|
|
939
1004
|
{t("designSystemSetup.privateRepoPrefix")}{" "}
|
|
940
1005
|
<a
|
|
@@ -954,6 +1019,13 @@ export default function DesignSystemSetup() {
|
|
|
954
1019
|
>
|
|
955
1020
|
<IconCheck className="w-3.5 h-3.5 text-green-400/60 shrink-0" />
|
|
956
1021
|
<span className="truncate flex-1">{link.url}</span>
|
|
1022
|
+
{link.ref || link.include?.length ? (
|
|
1023
|
+
<span className="shrink-0 text-[10px] text-muted-foreground/70">
|
|
1024
|
+
{[link.ref, link.include?.join(", ")]
|
|
1025
|
+
.filter(Boolean)
|
|
1026
|
+
.join(" · ")}
|
|
1027
|
+
</span>
|
|
1028
|
+
) : null}
|
|
957
1029
|
<button
|
|
958
1030
|
onClick={() => removeGithubLink(link.id)}
|
|
959
1031
|
className="text-muted-foreground/70 hover:text-muted-foreground shrink-0 cursor-pointer"
|
|
@@ -109,6 +109,8 @@ interface DesignSystemData {
|
|
|
109
109
|
logos?: Array<{ url?: string; name?: string; variant?: string }>;
|
|
110
110
|
defaults?: Record<string, unknown>;
|
|
111
111
|
notes?: unknown;
|
|
112
|
+
/** The source system's own named vocabulary; absent on kits predating it. */
|
|
113
|
+
tokens?: unknown;
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
export default function DesignSystems() {
|
|
@@ -1105,10 +1107,22 @@ function getDetailTokens(
|
|
|
1105
1107
|
const borders = data?.borders ?? {};
|
|
1106
1108
|
const defaults = data?.defaults ?? {};
|
|
1107
1109
|
const logos = data?.logos ?? [];
|
|
1110
|
+
const namedTokenCount = Array.isArray(data?.tokens) ? data.tokens.length : 0;
|
|
1108
1111
|
return [
|
|
1109
1112
|
...objectPreviewItems(t("designSystems.tokenPreview.spacing"), spacing),
|
|
1110
1113
|
...objectPreviewItems(t("designSystems.tokenPreview.borders"), borders),
|
|
1111
1114
|
...objectPreviewItems(t("designSystems.tokenPreview.defaults"), defaults),
|
|
1115
|
+
// The seven color roles are a summary of an import, not its extent. Without
|
|
1116
|
+
// this the panel renders a 200-token system identically to a 7-token one,
|
|
1117
|
+
// which reads as "it only captured a few colors".
|
|
1118
|
+
namedTokenCount > 0
|
|
1119
|
+
? {
|
|
1120
|
+
label: t("designSystems.tokenPreview.namedTokens"),
|
|
1121
|
+
value: t("designSystems.tokenPreview.savedCount", {
|
|
1122
|
+
count: namedTokenCount,
|
|
1123
|
+
}),
|
|
1124
|
+
}
|
|
1125
|
+
: null,
|
|
1112
1126
|
logos.length > 0
|
|
1113
1127
|
? {
|
|
1114
1128
|
label: t("designSystems.tokenPreview.logos"),
|