@agent-native/core 0.84.38 → 0.84.39

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.
@@ -373,6 +373,7 @@ interface DesignCanvasProps {
373
373
  }) => void;
374
374
  onElementDblClickText?: (info: ElementInfo) => void;
375
375
  onIframeHotkey?: (event: IframeHotkeyPayload) => void;
376
+ onFigmaClipboardPaste?: (event: IframeFigmaClipboardPastePayload) => void;
376
377
  onIframeContextMenu?: (event: IframeContextMenuPayload) => void;
377
378
  onEditorDragStateChange?: (active: boolean) => void;
378
379
  onVisualStructureChange?: (
@@ -612,6 +613,10 @@ export interface IframeHotkeyPayload {
612
613
  repeat: boolean;
613
614
  }
614
615
 
616
+ export interface IframeFigmaClipboardPastePayload {
617
+ content: string;
618
+ }
619
+
615
620
  export interface IframeContextMenuPayload {
616
621
  clientX: number;
617
622
  clientY: number;
@@ -653,6 +658,7 @@ export function DesignCanvas({
653
658
  onTextEditingStateChange,
654
659
  onElementDblClickText,
655
660
  onIframeHotkey,
661
+ onFigmaClipboardPaste,
656
662
  onIframeContextMenu,
657
663
  onEditorDragStateChange,
658
664
  onVisualStructureChange,
@@ -1168,6 +1174,12 @@ export function DesignCanvas({
1168
1174
  });
1169
1175
  return;
1170
1176
  }
1177
+ if (e.data.type === "figma-clipboard-paste") {
1178
+ const content =
1179
+ typeof e.data.content === "string" ? e.data.content : "";
1180
+ if (content) onFigmaClipboardPaste?.({ content });
1181
+ return;
1182
+ }
1171
1183
  if (e.data.type === "element-contextmenu") {
1172
1184
  const clientX = Number(e.data.clientX);
1173
1185
  const clientY = Number(e.data.clientY);
@@ -1291,6 +1303,7 @@ export function DesignCanvas({
1291
1303
  onTextEditingStateChange,
1292
1304
  onElementDblClickText,
1293
1305
  onIframeHotkey,
1306
+ onFigmaClipboardPaste,
1294
1307
  onIframeContextMenu,
1295
1308
  onEditorDragStateChange,
1296
1309
  onVisualStructureChange,
@@ -5,6 +5,7 @@ import {
5
5
  IconChevronRight,
6
6
  IconCircleCheck,
7
7
  IconCode,
8
+ IconCopy,
8
9
  IconHtml,
9
10
  IconUpload,
10
11
  } from "@tabler/icons-react";
@@ -23,6 +24,13 @@ import { Badge } from "@/components/ui/badge";
23
24
  import { Button } from "@/components/ui/button";
24
25
  import { Textarea } from "@/components/ui/textarea";
25
26
  import { sendToDesignAgentChat } from "@/lib/agent-chat";
27
+ import {
28
+ getFigmaClipboardContent,
29
+ importResultSummary,
30
+ looksLikeStandaloneHtml,
31
+ VISUAL_EDIT_CONNECT_COMMAND,
32
+ type ImportResult,
33
+ } from "@/lib/design-import";
26
34
  import { cn } from "@/lib/utils";
27
35
 
28
36
  import type { DesignExtensionSlotContext } from "./DesignExtensionsPanel";
@@ -31,31 +39,7 @@ interface DesignImportPanelProps {
31
39
  context: Pick<DesignExtensionSlotContext, "designId" | "viewMode">;
32
40
  }
33
41
 
34
- interface ImportResult {
35
- designId?: string;
36
- files?: Array<{ id: string; filename: string }>;
37
- warnings?: string[];
38
- error?: string;
39
- }
40
-
41
- type ImportMode = "figma-paste" | "fig-file" | "html";
42
-
43
- function hasFigmaPayload(html: string): boolean {
44
- return /\(figmeta\)|\(figma\)|data-metadata=|data-buffer=/i.test(html);
45
- }
46
-
47
- function looksLikeHtml(value: string): boolean {
48
- return /<(html|body|main|section|div|article|header|footer|button|img)\b/i.test(
49
- value,
50
- );
51
- }
52
-
53
- function resultSummary(result: ImportResult | undefined, fallback: string) {
54
- const count = result?.files?.length ?? 0;
55
- if (count === 0) return fallback;
56
- if (count === 1) return `Imported ${result!.files![0]!.filename}.`;
57
- return `Imported ${count} screens.`;
58
- }
42
+ type ImportMode = "figma-paste" | "fig-file" | "html" | "local-app";
59
43
 
60
44
  export function DesignImportPanel({ context }: DesignImportPanelProps) {
61
45
  const t = useT();
@@ -78,7 +62,7 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
78
62
  queryClient.invalidateQueries({ queryKey: ["action", "get-design"] }),
79
63
  queryClient.invalidateQueries({ queryKey: ["action"] }),
80
64
  ]);
81
- toast.success(resultSummary(result, fallback));
65
+ toast.success(importResultSummary(result, fallback));
82
66
  if (result?.warnings?.length) {
83
67
  toast.warning(t("designEditor.import.warningsToast"), {
84
68
  description: result.warnings[0],
@@ -91,7 +75,7 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
91
75
 
92
76
  const importHtmlString = useCallback(
93
77
  (content: string, originalName?: string) => {
94
- if (!looksLikeHtml(content)) {
78
+ if (!looksLikeStandaloneHtml(content)) {
95
79
  toast.error(t("designEditor.import.errors.notHtml"));
96
80
  return;
97
81
  }
@@ -129,13 +113,14 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
129
113
  const text = event.clipboardData.getData("text/plain");
130
114
  const content = html || text;
131
115
  if (!content) return;
132
- if (hasFigmaPayload(content)) {
116
+ const figmaContent = getFigmaClipboardContent(event.clipboardData);
117
+ if (figmaContent) {
133
118
  event.preventDefault();
134
119
  importSource.mutate(
135
120
  {
136
121
  designId: context.designId,
137
122
  sourceType: "figma-paste-html",
138
- content,
123
+ content: figmaContent,
139
124
  originalName: "figma-paste.html",
140
125
  },
141
126
  {
@@ -157,7 +142,7 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
157
142
  );
158
143
  return;
159
144
  }
160
- if (looksLikeHtml(content)) {
145
+ if (looksLikeStandaloneHtml(content)) {
161
146
  event.preventDefault();
162
147
  importHtmlString(content, "pasted-html.html");
163
148
  }
@@ -233,23 +218,32 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
233
218
  toast.success(t("designEditor.import.visualEditSent"));
234
219
  }, [t]);
235
220
 
221
+ const copyVisualEditCommand = useCallback(async () => {
222
+ try {
223
+ await navigator.clipboard.writeText(VISUAL_EDIT_CONNECT_COMMAND);
224
+ toast.success(t("designEditor.copied"));
225
+ } catch {
226
+ toast.error(t("designEditor.toasts.clipboardBlocked"));
227
+ }
228
+ }, [t]);
229
+
236
230
  const busy = importSource.isPending || uploading;
237
231
 
238
232
  return (
239
233
  <div className="flex min-h-0 flex-1 flex-col bg-background">
240
- <div className="flex h-16 shrink-0 items-center border-b border-border/60 px-4">
234
+ <div className="flex h-14 shrink-0 items-center border-b border-border/60 px-3.5">
241
235
  <div className="min-w-0">
242
- <h3 className="truncate text-xl font-semibold tracking-tight text-foreground">
236
+ <h3 className="truncate text-base font-semibold tracking-tight text-foreground">
243
237
  {t("designEditor.import.title")}
244
238
  </h3>
245
- <p className="mt-0.5 truncate text-xs text-muted-foreground">
239
+ <p className="mt-0.5 truncate text-[11px] text-muted-foreground">
246
240
  {"Bring source screens into this design" /* i18n-ignore */}
247
241
  </p>
248
242
  </div>
249
243
  </div>
250
244
 
251
- <div className="design-inspector-scroll min-h-0 flex-1 overflow-y-auto overscroll-contain px-4 pb-4 pt-4">
252
- <div className="space-y-1">
245
+ <div className="design-inspector-scroll min-h-0 flex-1 overflow-y-auto overscroll-contain px-3.5 pb-4 pt-3">
246
+ <div className="space-y-0.5">
253
247
  <ImportSourceRow
254
248
  id="figma-paste-import"
255
249
  icon={<IconBrandFigma className="size-3.5" />}
@@ -264,10 +258,11 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
264
258
  )
265
259
  }
266
260
  >
267
- <div className="p-2.5">
261
+ <div className="p-2">
268
262
  <div
269
263
  role="textbox"
270
264
  tabIndex={0}
265
+ data-hotkeys-scope="text"
271
266
  aria-label={t("designEditor.import.figmaPasteTarget")}
272
267
  onPaste={handlePaste}
273
268
  className={cn(
@@ -290,7 +285,7 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
290
285
  setActiveMode((mode) => (mode === "fig-file" ? null : "fig-file"))
291
286
  }
292
287
  >
293
- <div className="space-y-2 p-2.5">
288
+ <div className="space-y-2 p-2">
294
289
  <input
295
290
  ref={fileInputRef}
296
291
  type="file"
@@ -330,7 +325,7 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
330
325
  setActiveMode((mode) => (mode === "html" ? null : "html"))
331
326
  }
332
327
  >
333
- <div className="space-y-2 p-2.5">
328
+ <div className="space-y-2 p-2">
334
329
  <Textarea
335
330
  value={htmlText}
336
331
  onChange={(event) => setHtmlText(event.target.value)}
@@ -369,11 +364,11 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
369
364
  </ImportSourceRow>
370
365
  </div>
371
366
 
372
- <div className="mt-5 border-t border-border/60 pt-4">
373
- <p className="mb-2 text-xs font-medium text-muted-foreground">
367
+ <div className="mt-4 border-t border-border/60 pt-3">
368
+ <p className="mb-1.5 text-[11px] font-medium text-muted-foreground">
374
369
  {"More sources" /* i18n-ignore */}
375
370
  </p>
376
- <div className="space-y-1">
371
+ <div className="space-y-0.5">
377
372
  <CompactSourceRow
378
373
  icon={<IconBrandGithub className="size-3.5" />}
379
374
  title={t("designEditor.import.githubTitle")}
@@ -382,24 +377,47 @@ export function DesignImportPanel({ context }: DesignImportPanelProps) {
382
377
  }
383
378
  badge={t("designEditor.import.comingSoon")}
384
379
  />
385
- <CompactSourceRow
380
+ <ImportSourceRow
381
+ id="local-app-import"
386
382
  icon={<IconCode className="size-3.5" />}
387
383
  title={t("designEditor.import.localTitle")}
388
- description={
389
- "Connect a running app with visual-edit." /* i18n-ignore */
384
+ description={t("designEditor.import.localDescription")}
385
+ isOpen={activeMode === "local-app"}
386
+ onToggle={() =>
387
+ setActiveMode((mode) =>
388
+ mode === "local-app" ? null : "local-app",
389
+ )
390
390
  }
391
- badge={t("designEditor.import.comingSoon")}
392
- action={
391
+ >
392
+ <div className="space-y-2 p-2">
393
+ <p className="text-[11px] leading-snug text-muted-foreground">
394
+ {t("designEditor.import.visualEditGuidance")}
395
+ </p>
396
+ <div className="flex items-center gap-1.5 rounded-md border border-border/70 bg-muted/40 p-1.5">
397
+ <code className="min-w-0 flex-1 truncate font-mono text-[10px] leading-5 text-foreground/80">
398
+ {VISUAL_EDIT_CONNECT_COMMAND}
399
+ </code>
400
+ <Button
401
+ type="button"
402
+ size="sm"
403
+ variant="ghost"
404
+ className="h-6 shrink-0 px-1.5 text-[10px]"
405
+ onClick={copyVisualEditCommand}
406
+ >
407
+ <IconCopy className="size-3" />
408
+ {"Copy" /* i18n-ignore */}
409
+ </Button>
410
+ </div>
393
411
  <Button
394
412
  size="sm"
395
- variant="ghost"
396
- className="h-7 px-2 text-[11px]"
413
+ variant="outline"
414
+ className="h-7 w-full justify-center text-[11px]"
397
415
  onClick={askVisualEdit}
398
416
  >
399
417
  {t("designEditor.import.useVisualEditNow")}
400
418
  </Button>
401
- }
402
- />
419
+ </div>
420
+ </ImportSourceRow>
403
421
  </div>
404
422
  </div>
405
423
 
@@ -448,24 +466,24 @@ function ImportSourceRow({
448
466
  aria-controls={id}
449
467
  onClick={onToggle}
450
468
  className={cn(
451
- "group flex w-full cursor-pointer items-center gap-3 rounded-md px-2 py-2.5 text-left transition-colors hover:bg-accent/60 active:bg-accent",
469
+ "group flex w-full cursor-pointer items-center gap-2.5 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-accent/60 active:bg-accent",
452
470
  isOpen && "bg-accent/45",
453
471
  )}
454
472
  >
455
- <span className="flex size-9 shrink-0 items-center justify-center rounded-md border border-border/70 bg-muted/70 text-muted-foreground transition-colors group-hover:border-border group-hover:bg-muted">
473
+ <span className="flex size-8 shrink-0 items-center justify-center rounded-md border border-border/70 bg-muted/70 text-muted-foreground transition-colors group-hover:border-border group-hover:bg-muted">
456
474
  {icon}
457
475
  </span>
458
476
  <span className="min-w-0 flex-1">
459
- <span className="block truncate text-sm font-medium leading-tight text-foreground">
477
+ <span className="block truncate text-[13px] font-medium leading-tight text-foreground">
460
478
  {title}
461
479
  </span>
462
- <span className="mt-0.5 line-clamp-1 text-xs leading-snug text-muted-foreground">
480
+ <span className="mt-0.5 line-clamp-1 text-[11px] leading-snug text-muted-foreground">
463
481
  {description}
464
482
  </span>
465
483
  </span>
466
484
  <IconChevronRight
467
485
  className={cn(
468
- "size-4 shrink-0 text-muted-foreground transition-transform",
486
+ "size-3.5 shrink-0 text-muted-foreground transition-transform",
469
487
  isOpen && "rotate-90",
470
488
  )}
471
489
  />
@@ -473,7 +491,7 @@ function ImportSourceRow({
473
491
  {isOpen ? (
474
492
  <div
475
493
  id={id}
476
- className="mb-2 mt-1 overflow-hidden rounded-md border border-border/70 bg-background/70"
494
+ className="mb-1.5 mt-1 overflow-hidden rounded-md border border-border/70 bg-background/70"
477
495
  >
478
496
  {children}
479
497
  </div>
@@ -496,13 +514,13 @@ function CompactSourceRow({
496
514
  action?: ReactNode;
497
515
  }) {
498
516
  return (
499
- <div className="flex items-center gap-2 rounded-md px-2 py-2 text-left opacity-85">
517
+ <div className="flex items-center gap-2 rounded-md px-2 py-1.5 text-left opacity-85">
500
518
  <span className="flex size-8 shrink-0 items-center justify-center rounded-md border border-border/60 bg-muted/50 text-muted-foreground">
501
519
  {icon}
502
520
  </span>
503
521
  <span className="min-w-0 flex-1">
504
522
  <span className="flex items-center gap-1.5">
505
- <span className="truncate text-xs font-medium text-foreground">
523
+ <span className="truncate text-[13px] font-medium text-foreground">
506
524
  {title}
507
525
  </span>
508
526
  <Badge variant="secondary" className="h-4 px-1 text-[9px]">
@@ -53,6 +53,7 @@ import {
53
53
  LIGHTWEIGHT_HIT_TEST_BRIDGE_SCRIPT,
54
54
  appendHitTestResponder,
55
55
  type IframeContextMenuPayload,
56
+ type IframeFigmaClipboardPastePayload,
56
57
  type IframeHotkeyPayload,
57
58
  } from "./DesignCanvas";
58
59
  import {
@@ -323,6 +324,9 @@ interface MultiScreenCanvasProps {
323
324
  onBoardElementClear?: () => void;
324
325
  onBoardElementDblClickText?: (info: ElementInfo) => void;
325
326
  onBoardIframeHotkey?: (event: IframeHotkeyPayload) => void;
327
+ onBoardFigmaClipboardPaste?: (
328
+ event: IframeFigmaClipboardPastePayload,
329
+ ) => void;
326
330
  onBoardIframeContextMenu?: (event: IframeContextMenuPayload) => void;
327
331
  onBoardTextEditingStateChange?: (state: {
328
332
  active: boolean;
@@ -1142,6 +1146,7 @@ export function MultiScreenCanvas({
1142
1146
  onBoardElementClear,
1143
1147
  onBoardElementDblClickText,
1144
1148
  onBoardIframeHotkey,
1149
+ onBoardFigmaClipboardPaste,
1145
1150
  onBoardIframeContextMenu,
1146
1151
  onBoardTextEditingStateChange,
1147
1152
  boardClearSelectionRequest,
@@ -4949,6 +4954,7 @@ export function MultiScreenCanvas({
4949
4954
  onElementHover={onBoardElementHover ?? (() => {})}
4950
4955
  onClearSelection={onBoardElementClear}
4951
4956
  onIframeHotkey={onBoardIframeHotkey}
4957
+ onFigmaClipboardPaste={onBoardFigmaClipboardPaste}
4952
4958
  onIframeContextMenu={onBoardIframeContextMenu}
4953
4959
  onVisualStructureChange={onBoardVisualStructureChange}
4954
4960
  onVisualStyleChange={onBoardVisualStyleChange}
@@ -4965,26 +4965,98 @@ declare var __DESIGN_CANVAS_BOARD_SURFACE__: boolean;
4965
4965
  true,
4966
4966
  );
4967
4967
 
4968
+ var pendingPlainPasteHotkeyTimer: number | null = null;
4969
+
4970
+ function clearPendingPlainPasteHotkey() {
4971
+ if (pendingPlainPasteHotkeyTimer === null) return;
4972
+ window.clearTimeout(pendingPlainPasteHotkeyTimer);
4973
+ pendingPlainPasteHotkeyTimer = null;
4974
+ }
4975
+
4976
+ function postDesignHotkey(payload) {
4977
+ (window.parent as Window).postMessage(
4978
+ {
4979
+ type: "design-hotkey",
4980
+ key: payload.key,
4981
+ code: payload.code,
4982
+ metaKey: !!payload.metaKey,
4983
+ ctrlKey: !!payload.ctrlKey,
4984
+ shiftKey: !!payload.shiftKey,
4985
+ altKey: !!payload.altKey,
4986
+ repeat: !!payload.repeat,
4987
+ },
4988
+ "*",
4989
+ );
4990
+ }
4991
+
4968
4992
  document.addEventListener(
4969
4993
  "keydown",
4970
4994
  function (e) {
4971
4995
  if (!shouldForwardDesignHotkey(e)) return;
4996
+ var key = e.key;
4997
+ var normalized = key && key.length === 1 ? key.toLowerCase() : key;
4998
+ var primary = e.metaKey || e.ctrlKey;
4999
+ var plainPasteHotkey =
5000
+ primary && normalized === "v" && !e.altKey && !e.shiftKey;
4972
5001
  if (e.key === "Escape" && cancelActiveBridgeDrag()) {
4973
5002
  stopNativeInteraction(e);
4974
5003
  return;
4975
5004
  }
5005
+ var payload = {
5006
+ key: e.key,
5007
+ code: e.code,
5008
+ metaKey: !!e.metaKey,
5009
+ ctrlKey: !!e.ctrlKey,
5010
+ shiftKey: !!e.shiftKey,
5011
+ altKey: !!e.altKey,
5012
+ repeat: !!e.repeat,
5013
+ };
5014
+ if (plainPasteHotkey) {
5015
+ clearPendingPlainPasteHotkey();
5016
+ pendingPlainPasteHotkeyTimer = window.setTimeout(function () {
5017
+ pendingPlainPasteHotkeyTimer = null;
5018
+ postDesignHotkey(payload);
5019
+ }, 0);
5020
+ return;
5021
+ }
4976
5022
  stopNativeInteraction(e);
4977
5023
  if (e.key === "Escape") clearRuntimeSelection();
5024
+ postDesignHotkey(payload);
5025
+ },
5026
+ true,
5027
+ );
5028
+
5029
+ function hasFigmaClipboardPayload(value) {
5030
+ return /<[^>]+\sdata-(metadata|buffer)=["'][^"']*\((figmeta|figma)\)[^"']*["']/i.test(
5031
+ String(value || ""),
5032
+ );
5033
+ }
5034
+
5035
+ function getFigmaClipboardContent(data) {
5036
+ if (!data || !data.getData) return "";
5037
+ var html = data.getData("text/html") || "";
5038
+ if (hasFigmaClipboardPayload(html)) return html;
5039
+ var text = data.getData("text/plain") || "";
5040
+ return hasFigmaClipboardPayload(text) ? text : "";
5041
+ }
5042
+
5043
+ document.addEventListener(
5044
+ "paste",
5045
+ function (e) {
5046
+ if (
5047
+ (activeTextEditEl && e.target && activeTextEditEl.contains(e.target)) ||
5048
+ isEditorTypingTarget(e.target)
5049
+ ) {
5050
+ return;
5051
+ }
5052
+ var content = getFigmaClipboardContent(e.clipboardData);
5053
+ clearPendingPlainPasteHotkey();
5054
+ if (!content) return;
5055
+ stopNativeInteraction(e);
4978
5056
  (window.parent as Window).postMessage(
4979
5057
  {
4980
- type: "design-hotkey",
4981
- key: e.key,
4982
- code: e.code,
4983
- metaKey: !!e.metaKey,
4984
- ctrlKey: !!e.ctrlKey,
4985
- shiftKey: !!e.shiftKey,
4986
- altKey: !!e.altKey,
4987
- repeat: !!e.repeat,
5058
+ type: "figma-clipboard-paste",
5059
+ content: content,
4988
5060
  },
4989
5061
  "*",
4990
5062
  );
@@ -294,9 +294,9 @@ const messages = {
294
294
  githubTitle: "GitHub",
295
295
  githubDescription: "即將推出:直接從儲存庫匯入螢幕和元件。",
296
296
  localTitle: "本機 app / VS Code",
297
- localDescription: "即將推出:連接執行中的本機 app 並匯入 URL 螢幕。",
297
+ localDescription: "使用 visual-edit 連接執行中的本機 app。",
298
298
  visualEditGuidance:
299
- "目前可請代理使用 visual-edit。它可以執行 app、呼叫 `npx @agent-native/core@latest design connect`,並新增 URL 螢幕。",
299
+ "啟動 app,在 app repo 中執行下方命令,然後請代理使用 visual-edit skill 新增 URL 螢幕。",
300
300
  useVisualEditNow: "立即使用 visual-edit",
301
301
  comingSoon: "即將推出",
302
302
  warningsToast: "匯入完成但有警告",
@@ -301,10 +301,9 @@ const enUS = {
301
301
  githubDescription:
302
302
  "Coming soon: import screens and components directly from a repository.",
303
303
  localTitle: "Local app / VS Code",
304
- localDescription:
305
- "Coming soon: connect a running local app and import URL-backed screens.",
304
+ localDescription: "Connect a running local app with visual-edit.",
306
305
  visualEditGuidance:
307
- "Today, ask the agent to use visual-edit. It can run the app, call `npx @agent-native/core@latest design connect`, and add URL-backed screens.",
306
+ "Start your app, run the command below from the app repo, then ask the agent to use the visual-edit skill to add URL-backed screens.",
308
307
  useVisualEditNow: "Use visual-edit now",
309
308
  comingSoon: "Coming soon",
310
309
  warningsToast: "Import completed with warnings",
@@ -10116,9 +10115,9 @@ const designImportOverrides = {
10116
10115
  githubTitle: "GitHub",
10117
10116
  githubDescription: "即將推出:直接從儲存庫匯入螢幕和元件。",
10118
10117
  localTitle: "本機 app / VS Code",
10119
- localDescription: "即將推出:連接執行中的本機 app 並匯入 URL 螢幕。",
10118
+ localDescription: "使用 visual-edit 連接執行中的本機 app。",
10120
10119
  visualEditGuidance:
10121
- "目前可請代理使用 visual-edit。它可以執行 app、呼叫 `npx @agent-native/core@latest design connect`,並新增 URL 螢幕。",
10120
+ "啟動 app,在 app repo 中執行下方命令,然後請代理使用 visual-edit skill 新增 URL 螢幕。",
10122
10121
  useVisualEditNow: "立即使用 visual-edit",
10123
10122
  comingSoon: "即將推出",
10124
10123
  warningsToast: "匯入完成但有警告",
@@ -10158,9 +10157,9 @@ const designImportOverrides = {
10158
10157
  githubTitle: "GitHub",
10159
10158
  githubDescription: "即将推出:直接从仓库导入屏幕和组件。",
10160
10159
  localTitle: "本地 app / VS Code",
10161
- localDescription: "即将推出:连接正在运行的本地 app 并导入 URL 屏幕。",
10160
+ localDescription: "使用 visual-edit 连接正在运行的本地 app。",
10162
10161
  visualEditGuidance:
10163
- "现在可以让代理使用 visual-edit。它可以运行 app,调用 `npx @agent-native/core@latest design connect`,并添加 URL 屏幕。",
10162
+ "启动 app,在 app repo 中运行下方命令,然后让代理使用 visual-edit skill 添加 URL 屏幕。",
10164
10163
  useVisualEditNow: "立即使用 visual-edit",
10165
10164
  comingSoon: "即将推出",
10166
10165
  warningsToast: "导入完成但有警告",
@@ -10202,10 +10201,9 @@ const designImportOverrides = {
10202
10201
  githubDescription:
10203
10202
  "Próximamente: importar pantallas y componentes directamente desde un repositorio.",
10204
10203
  localTitle: "App local / VS Code",
10205
- localDescription:
10206
- "Próximamente: conectar una app local en ejecución e importar pantallas con URL.",
10204
+ localDescription: "Conecta una app local en ejecución con visual-edit.",
10207
10205
  visualEditGuidance:
10208
- "Hoy puedes pedir al agente que use visual-edit. Puede ejecutar la app, llamar a `npx @agent-native/core@latest design connect` y añadir pantallas con URL.",
10206
+ "Inicia tu app, ejecuta el comando siguiente desde el repo de la app y luego pide al agente que use la skill visual-edit para añadir pantallas con URL.",
10209
10207
  useVisualEditNow: "Usar visual-edit ahora",
10210
10208
  comingSoon: "Próximamente",
10211
10209
  warningsToast: "La importación terminó con advertencias",
@@ -10248,9 +10246,9 @@ const designImportOverrides = {
10248
10246
  "Bientôt : importer des écrans et composants directement depuis un dépôt.",
10249
10247
  localTitle: "App locale / VS Code",
10250
10248
  localDescription:
10251
- "Bientôt : connecter une app locale en cours d’exécution et importer des écrans par URL.",
10249
+ "Connectez une app locale en cours d’exécution avec visual-edit.",
10252
10250
  visualEditGuidance:
10253
- "Aujourd’hui, demandez à l’agent d’utiliser visual-edit. Il peut lancer l’app, appeler `npx @agent-native/core@latest design connect` et ajouter des écrans par URL.",
10251
+ "Lancez votre app, exécutez la commande ci-dessous depuis le dépôt de l’app, puis demandez à l’agent d’utiliser la skill visual-edit pour ajouter des écrans par URL.",
10254
10252
  useVisualEditNow: "Utiliser visual-edit maintenant",
10255
10253
  comingSoon: "Bientôt",
10256
10254
  warningsToast: "Import terminé avec avertissements",
@@ -10292,10 +10290,9 @@ const designImportOverrides = {
10292
10290
  githubDescription:
10293
10291
  "Demnächst: Bildschirme und Komponenten direkt aus einem Repository importieren.",
10294
10292
  localTitle: "Lokale App / VS Code",
10295
- localDescription:
10296
- "Demnächst: eine laufende lokale App verbinden und URL-basierte Bildschirme importieren.",
10293
+ localDescription: "Verbinde eine laufende lokale App mit visual-edit.",
10297
10294
  visualEditGuidance:
10298
- "Heute kannst du den Agenten bitten, visual-edit zu verwenden. Er kann die App starten, `npx @agent-native/core@latest design connect` aufrufen und URL-basierte Bildschirme hinzufügen.",
10295
+ "Starte deine App, führe den folgenden Befehl im App-Repo aus und bitte den Agenten dann, die visual-edit-Skill zu verwenden, um URL-basierte Bildschirme hinzuzufügen.",
10299
10296
  useVisualEditNow: "visual-edit jetzt verwenden",
10300
10297
  comingSoon: "Demnächst",
10301
10298
  warningsToast: "Import mit Warnungen abgeschlossen",
@@ -10337,10 +10334,9 @@ const designImportOverrides = {
10337
10334
  githubDescription:
10338
10335
  "近日対応: リポジトリから画面とコンポーネントを直接インポートします。",
10339
10336
  localTitle: "ローカル app / VS Code",
10340
- localDescription:
10341
- "近日対応: 実行中のローカル app に接続し、URL ベースの画面をインポートします。",
10337
+ localDescription: "visual-edit で実行中のローカル app に接続します。",
10342
10338
  visualEditGuidance:
10343
- "現在はエージェントに visual-edit の使用を依頼できます。app を起動し、`npx @agent-native/core@latest design connect` を呼び出して URL ベースの画面を追加できます。",
10339
+ "app を起動し、app repo で下のコマンドを実行してから、エージェントに visual-edit skill URL ベースの画面を追加するよう依頼してください。",
10344
10340
  useVisualEditNow: "visual-edit を今すぐ使う",
10345
10341
  comingSoon: "近日対応",
10346
10342
  warningsToast: "警告付きでインポートが完了しました",
@@ -10382,10 +10378,9 @@ const designImportOverrides = {
10382
10378
  githubDescription:
10383
10379
  "곧 제공: 저장소에서 화면과 컴포넌트를 직접 가져옵니다.",
10384
10380
  localTitle: "로컬 app / VS Code",
10385
- localDescription:
10386
- "곧 제공: 실행 중인 로컬 app을 연결하고 URL 기반 화면을 가져옵니다.",
10381
+ localDescription: "visual-edit로 실행 중인 로컬 app을 연결합니다.",
10387
10382
  visualEditGuidance:
10388
- "지금은 에이전트에게 visual-edit 사용을 요청하세요. app을 실행하고 `npx @agent-native/core@latest design connect`를 호출한 뒤 URL 기반 화면을 추가할 있습니다.",
10383
+ "app을 시작하고 app repo에서 아래 명령을 실행한 다음, 에이전트에게 visual-edit skill로 URL 기반 화면을 추가해 달라고 요청하세요.",
10389
10384
  useVisualEditNow: "지금 visual-edit 사용",
10390
10385
  comingSoon: "곧 제공",
10391
10386
  warningsToast: "경고와 함께 가져오기가 완료되었습니다",
@@ -10427,10 +10422,9 @@ const designImportOverrides = {
10427
10422
  githubDescription:
10428
10423
  "Em breve: importe telas e componentes diretamente de um repositório.",
10429
10424
  localTitle: "App local / VS Code",
10430
- localDescription:
10431
- "Em breve: conecte um app local em execução e importe telas por URL.",
10425
+ localDescription: "Conecte um app local em execução com visual-edit.",
10432
10426
  visualEditGuidance:
10433
- "Hoje, peça ao agente para usar visual-edit. Ele pode executar o app, chamar `npx @agent-native/core@latest design connect` e adicionar telas por URL.",
10427
+ "Inicie seu app, execute o comando abaixo no repo do app e depois peça ao agente para usar a skill visual-edit para adicionar telas por URL.",
10434
10428
  useVisualEditNow: "Usar visual-edit agora",
10435
10429
  comingSoon: "Em breve",
10436
10430
  warningsToast: "Importação concluída com avisos",
@@ -10472,10 +10466,9 @@ const designImportOverrides = {
10472
10466
  githubDescription:
10473
10467
  "जल्द आ रहा है: repository से screens और components सीधे import करें।",
10474
10468
  localTitle: "स्थानीय app / VS Code",
10475
- localDescription:
10476
- "जल्द आ रहा है: चल रहे local app को connect करके URL-backed screens import करें।",
10469
+ localDescription: "चल रहे local app को visual-edit से connect करें।",
10477
10470
  visualEditGuidance:
10478
- "आज agent से visual-edit skill इस्तेमाल करने को कहें। यह app चला सकता है, `npx @agent-native/core@latest design connect` call कर सकता है, और URL-backed screens जोड़ सकता है।",
10471
+ "अपना app शुरू करें, app repo से नीचे वाला command चलाएँ, फिर agent से visual-edit skill इस्तेमाल करके URL-backed screens जोड़ने को कहें।",
10479
10472
  useVisualEditNow: "अभी visual-edit इस्तेमाल करें",
10480
10473
  comingSoon: "जल्द आ रहा है",
10481
10474
  warningsToast: "Import warnings के साथ पूरा हुआ",
@@ -10516,10 +10509,9 @@ const designImportOverrides = {
10516
10509
  githubTitle: "GitHub",
10517
10510
  githubDescription: "قريبا: استيراد الشاشات والمكونات مباشرة من مستودع.",
10518
10511
  localTitle: "تطبيق محلي / VS Code",
10519
- localDescription:
10520
- "قريبا: توصيل تطبيق محلي قيد التشغيل واستيراد شاشات مدعومة بروابط URL.",
10512
+ localDescription: "وصّل تطبيقا محليا قيد التشغيل باستخدام visual-edit.",
10521
10513
  visualEditGuidance:
10522
- "اليوم، اطلب من الوكيل استخدام visual-edit. يمكنه تشغيل التطبيق واستدعاء `npx @agent-native/core@latest design connect` وإضافة شاشات مدعومة بروابط URL.",
10514
+ "شغّل التطبيق، ثم نفّذ الأمر أدناه من مستودع التطبيق، وبعدها اطلب من الوكيل استخدام مهارة visual-edit لإضافة شاشات مدعومة بروابط URL.",
10523
10515
  useVisualEditNow: "استخدم visual-edit الآن",
10524
10516
  comingSoon: "قريبا",
10525
10517
  warningsToast: "اكتمل الاستيراد مع تحذيرات",