@agent-native/core 0.80.9 → 0.80.11
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/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +108 -15
- package/corpus/core/src/cli/design-connect.ts +28 -2
- package/corpus/core/src/cli/skills.ts +45 -24
- package/corpus/core/src/client/AssistantChat.tsx +123 -26
- package/corpus/core/src/client/sse-event-processor.ts +9 -0
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +9 -2
- package/corpus/templates/assets/AGENTS.md +4 -0
- package/corpus/templates/assets/actions/_tool-activity.ts +46 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +26 -5
- package/corpus/templates/assets/actions/generate-image.ts +118 -67
- package/corpus/templates/assets/actions/list-draft-assets.ts +50 -0
- package/corpus/templates/assets/actions/rerun-generation-run.ts +52 -31
- package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +100 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +7 -0
- package/corpus/templates/assets/app/i18n-data.ts +61 -0
- package/corpus/templates/assets/app/routes/_index.tsx +4 -0
- package/corpus/templates/assets/app/routes/library.tsx +145 -38
- package/corpus/templates/assets/changelog/2026-06-29-image-generation-can-now-render-requested-text-and-respect-b.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-image-generation-no-longer-looks-stuck-while-the-provider-is-still-working.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-tagged-presets-now-control-the-image-aspect-ratio.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +135 -11
- package/corpus/templates/assets/shared/api.ts +4 -0
- package/corpus/templates/clips/actions/list-ai-requests.ts +60 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +24 -25
- package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +717 -0
- package/corpus/templates/design/actions/add-breakpoint.ts +143 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +5 -0
- package/corpus/templates/design/actions/apply-a11y-fix.ts +317 -0
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +441 -0
- package/corpus/templates/design/actions/apply-design-state.ts +213 -0
- package/corpus/templates/design/actions/apply-design-token-edit.ts +202 -0
- package/corpus/templates/design/actions/apply-motion-edit.ts +413 -0
- package/corpus/templates/design/actions/apply-shader-fill.ts +404 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +191 -5
- package/corpus/templates/design/actions/capture-design-state.ts +224 -0
- package/corpus/templates/design/actions/connect-builder-app.ts +162 -0
- package/corpus/templates/design/actions/create-component.ts +447 -0
- package/corpus/templates/design/actions/create-design-branch.ts +263 -0
- package/corpus/templates/design/actions/create-design-state.ts +162 -0
- package/corpus/templates/design/actions/delete-design-state.ts +55 -0
- package/corpus/templates/design/actions/delete-design.ts +20 -0
- package/corpus/templates/design/actions/deploy-design-preview.ts +275 -0
- package/corpus/templates/design/actions/get-component-details.ts +251 -0
- package/corpus/templates/design/actions/get-design-branch-diff.ts +362 -0
- package/corpus/templates/design/actions/get-design-review.ts +314 -0
- package/corpus/templates/design/actions/get-design-surface-index.ts +582 -0
- package/corpus/templates/design/actions/get-motion-timeline.ts +99 -0
- package/corpus/templates/design/actions/index-components.ts +258 -0
- package/corpus/templates/design/actions/index-design-tokens.ts +277 -0
- package/corpus/templates/design/actions/list-design-extensions.ts +309 -0
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +153 -0
- package/corpus/templates/design/actions/list-design-states.ts +90 -0
- package/corpus/templates/design/actions/migrate-inline-design-to-app.ts +298 -0
- package/corpus/templates/design/actions/open-component-source.ts +242 -0
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +260 -0
- package/corpus/templates/design/actions/preview-design-token-edit.ts +113 -0
- package/corpus/templates/design/actions/preview-shader-fill.ts +187 -0
- package/corpus/templates/design/actions/remove-breakpoint.ts +103 -0
- package/corpus/templates/design/actions/remove-motion-timeline.ts +196 -0
- package/corpus/templates/design/actions/run-design-audit.ts +436 -0
- package/corpus/templates/design/actions/run-design-extension-action.ts +284 -0
- package/corpus/templates/design/actions/set-active-breakpoint.ts +39 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1550 -82
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +649 -43
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1788 -52
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +114 -33
- package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +157 -0
- package/corpus/templates/design/app/components/design/MotionDock.tsx +1071 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1053 -99
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +766 -0
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +581 -0
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +578 -0
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +241 -0
- package/corpus/templates/design/app/components/design/index.ts +16 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +66 -3
- package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +145 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +42 -12
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +131 -0
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -1
- package/corpus/templates/design/app/i18n/zh-TW.ts +32 -0
- package/corpus/templates/design/app/i18n-data.ts +280 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +3087 -490
- package/corpus/templates/design/changelog/2026-06-29-added-a-review-panel-in-the-design-editor-s-inspector-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-copying-and-pasting-layers-no-longer-shows-success-notificat.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-device-presets-in-all-screens-view-resize-the-selected-previ.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-and-canvas-drags-keep-the-layer-list-stable-while-chan.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-moves-can-be-undone-and-redone-without-flashing-the-ca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-previews-use-a-single-blue-hover-border-in-all-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-selected-containers-show-draggable-padding-and-gap-guides-on.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-design-editor-adds-a-studio-layer-with-tokens-respon.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-accessibility-findings-now-offer-a-one-click-fix.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-instances-now-have-editable-props-in-the-inspe.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-token-edits-now-stay-visible-in-previews-and-token-li.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-inspect-code-now-shows-the-elements-opening-tag-at-a-gla.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-shader-fill-presets-can-now-be-applied-to-an-element.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-can-now-add-a-track-to-any-element-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-visual-editor-selection-layer-paint-and-drawing-controls-are-more-reliable.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +94 -2
- package/corpus/templates/design/e2e/helpers.ts +10 -4
- package/corpus/templates/design/server/db/schema.ts +123 -0
- package/corpus/templates/design/server/plugins/db.ts +90 -0
- package/corpus/templates/design/shared/builder-app.ts +297 -0
- package/corpus/templates/design/shared/capability-resolver.ts +123 -0
- package/corpus/templates/design/shared/capture-sanitize.ts +70 -0
- package/corpus/templates/design/shared/code-layer.ts +1016 -71
- package/corpus/templates/design/shared/component-model.ts +274 -0
- package/corpus/templates/design/shared/design-review.ts +275 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +286 -0
- package/corpus/templates/design/shared/design-state.ts +112 -0
- package/corpus/templates/design/shared/design-surface-index.ts +258 -0
- package/corpus/templates/design/shared/motion-compiler.ts +349 -0
- package/corpus/templates/design/shared/motion-timeline.ts +193 -0
- package/corpus/templates/design/shared/resolve-tweaks.ts +32 -9
- package/corpus/templates/design/shared/responsive-classes.ts +452 -0
- package/corpus/templates/design/shared/shader-fill.ts +323 -0
- package/corpus/templates/design/shared/source-mode.ts +245 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +6 -2
- package/corpus/templates/plan/changelog/2026-06-29-plan-canvases-open-without-an-initial-pan-and-zoom-flicker.md +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +94 -10
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +28 -2
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +37 -21
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +115 -22
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +8 -8
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
|
@@ -826,6 +826,13 @@ const enUS = {
|
|
|
826
826
|
noMatchingAssets: "No matching assets across your kits.",
|
|
827
827
|
noMatchingLibraryAssets:
|
|
828
828
|
"No matching {{mediaLabel}} assets in this library.",
|
|
829
|
+
drafts: "Drafts",
|
|
830
|
+
allLibraries: "All libraries",
|
|
831
|
+
noDrafts: "No drafts yet.",
|
|
832
|
+
noMatchingDrafts: "No matching drafts.",
|
|
833
|
+
recentDrafts: "Recent Drafts",
|
|
834
|
+
viewAllDrafts: "View all drafts",
|
|
835
|
+
draftAsset: "Draft asset",
|
|
829
836
|
noReusableAssets:
|
|
830
837
|
"No reusable assets yet. Select a kit to upload references or generate assets.",
|
|
831
838
|
noNewAssetsUploaded: "No new assets were uploaded.",
|
|
@@ -2762,6 +2769,12 @@ export const messagesByLocale = {
|
|
|
2762
2769
|
"zh-TW": mergeMessages(zhTW),
|
|
2763
2770
|
"zh-CN": mergeMessages({
|
|
2764
2771
|
library: {
|
|
2772
|
+
allLibraries: "所有库",
|
|
2773
|
+
noDrafts: "暂无草稿。",
|
|
2774
|
+
noMatchingDrafts: "没有匹配的草稿。",
|
|
2775
|
+
recentDrafts: "最近草稿",
|
|
2776
|
+
viewAllDrafts: "查看所有草稿",
|
|
2777
|
+
draftAsset: "草稿资产",
|
|
2765
2778
|
addAssets: "添加资产",
|
|
2766
2779
|
addAssetsDescription:
|
|
2767
2780
|
"上传源素材或生成候选项,然后只将应指导未来生成的资产标记为参考。",
|
|
@@ -3500,6 +3513,12 @@ export const messagesByLocale = {
|
|
|
3500
3513
|
}),
|
|
3501
3514
|
"es-ES": mergeMessages({
|
|
3502
3515
|
library: {
|
|
3516
|
+
allLibraries: "Todas las bibliotecas",
|
|
3517
|
+
noDrafts: "Aún no hay borradores.",
|
|
3518
|
+
noMatchingDrafts: "No hay borradores coincidentes.",
|
|
3519
|
+
recentDrafts: "Borradores recientes",
|
|
3520
|
+
viewAllDrafts: "Ver todos los borradores",
|
|
3521
|
+
draftAsset: "Borrador",
|
|
3503
3522
|
addAssets: "Agregar activos",
|
|
3504
3523
|
addAssetsDescription:
|
|
3505
3524
|
"Cargue material fuente o genere candidatos, luego marque solo los activos que deberían guiar a las generaciones futuras como referencias.",
|
|
@@ -3963,6 +3982,12 @@ export const messagesByLocale = {
|
|
|
3963
3982
|
}),
|
|
3964
3983
|
"fr-FR": mergeMessages({
|
|
3965
3984
|
library: {
|
|
3985
|
+
allLibraries: "Toutes les bibliothèques",
|
|
3986
|
+
noDrafts: "Aucun brouillon pour l'instant.",
|
|
3987
|
+
noMatchingDrafts: "Aucun brouillon correspondant.",
|
|
3988
|
+
recentDrafts: "Brouillons récents",
|
|
3989
|
+
viewAllDrafts: "Voir tous les brouillons",
|
|
3990
|
+
draftAsset: "Brouillon",
|
|
3966
3991
|
addAssets: "Ajouter des éléments",
|
|
3967
3992
|
addAssetsDescription:
|
|
3968
3993
|
"Téléchargez le matériel source ou générez des candidats, puis marquez uniquement les atouts qui devraient guider les générations futures comme références.",
|
|
@@ -4404,6 +4429,12 @@ export const messagesByLocale = {
|
|
|
4404
4429
|
}),
|
|
4405
4430
|
"de-DE": mergeMessages({
|
|
4406
4431
|
library: {
|
|
4432
|
+
allLibraries: "Alle Bibliotheken",
|
|
4433
|
+
noDrafts: "Noch keine Entwürfe.",
|
|
4434
|
+
noMatchingDrafts: "Keine passenden Entwürfe.",
|
|
4435
|
+
recentDrafts: "Letzte Entwürfe",
|
|
4436
|
+
viewAllDrafts: "Alle Entwürfe anzeigen",
|
|
4437
|
+
draftAsset: "Entwurf",
|
|
4407
4438
|
addAssets: "Assets hinzufügen",
|
|
4408
4439
|
addAssetsDescription:
|
|
4409
4440
|
"Laden Sie Quellmaterial hoch oder generieren Sie Kandidaten und markieren Sie dann nur die Assets, die künftigen Generationen als Referenz dienen sollen.",
|
|
@@ -4753,6 +4784,12 @@ export const messagesByLocale = {
|
|
|
4753
4784
|
}),
|
|
4754
4785
|
"ja-JP": mergeMessages({
|
|
4755
4786
|
library: {
|
|
4787
|
+
allLibraries: "すべてのライブラリ",
|
|
4788
|
+
noDrafts: "下書きはまだありません。",
|
|
4789
|
+
noMatchingDrafts: "一致する下書きはありません。",
|
|
4790
|
+
recentDrafts: "最近の下書き",
|
|
4791
|
+
viewAllDrafts: "すべての下書きを表示",
|
|
4792
|
+
draftAsset: "下書きアセット",
|
|
4756
4793
|
addAssets: "アセットの追加",
|
|
4757
4794
|
addAssetsDescription:
|
|
4758
4795
|
"ソース素材をアップロードするか候補を生成し、将来の世代を導く必要がある資産のみを参照としてマークします。",
|
|
@@ -5092,6 +5129,12 @@ export const messagesByLocale = {
|
|
|
5092
5129
|
}),
|
|
5093
5130
|
"ko-KR": mergeMessages({
|
|
5094
5131
|
library: {
|
|
5132
|
+
allLibraries: "모든 라이브러리",
|
|
5133
|
+
noDrafts: "아직 초안이 없습니다.",
|
|
5134
|
+
noMatchingDrafts: "일치하는 초안이 없습니다.",
|
|
5135
|
+
recentDrafts: "최근 초안",
|
|
5136
|
+
viewAllDrafts: "모든 초안 보기",
|
|
5137
|
+
draftAsset: "초안 자산",
|
|
5095
5138
|
addAssets: "자산 추가",
|
|
5096
5139
|
addAssetsDescription:
|
|
5097
5140
|
"원본 자료를 업로드하거나 후보를 생성한 후, 미래 세대를 이끌어야 할 자산만 참고 자료로 표시하세요.",
|
|
@@ -5430,6 +5473,12 @@ export const messagesByLocale = {
|
|
|
5430
5473
|
}),
|
|
5431
5474
|
"pt-BR": mergeMessages({
|
|
5432
5475
|
library: {
|
|
5476
|
+
allLibraries: "Todas as bibliotecas",
|
|
5477
|
+
noDrafts: "Ainda não há rascunhos.",
|
|
5478
|
+
noMatchingDrafts: "Nenhum rascunho correspondente.",
|
|
5479
|
+
recentDrafts: "Rascunhos recentes",
|
|
5480
|
+
viewAllDrafts: "Ver todos os rascunhos",
|
|
5481
|
+
draftAsset: "Rascunho",
|
|
5433
5482
|
addAssets: "Adicionar recursos",
|
|
5434
5483
|
addAssetsDescription:
|
|
5435
5484
|
"Carregue o material de origem ou gere candidatos e marque apenas os ativos que devem orientar as gerações futuras como referências.",
|
|
@@ -5870,6 +5919,12 @@ export const messagesByLocale = {
|
|
|
5870
5919
|
}),
|
|
5871
5920
|
"hi-IN": mergeMessages({
|
|
5872
5921
|
library: {
|
|
5922
|
+
allLibraries: "सभी लाइब्रेरी",
|
|
5923
|
+
noDrafts: "अभी तक कोई ड्राफ़्ट नहीं।",
|
|
5924
|
+
noMatchingDrafts: "कोई मिलान वाला ड्राफ़्ट नहीं।",
|
|
5925
|
+
recentDrafts: "हाल के ड्राफ़्ट",
|
|
5926
|
+
viewAllDrafts: "सभी ड्राफ़्ट देखें",
|
|
5927
|
+
draftAsset: "ड्राफ़्ट एसेट",
|
|
5873
5928
|
addAssets: "संपत्तियां जोड़ें",
|
|
5874
5929
|
addAssetsDescription:
|
|
5875
5930
|
"स्रोत सामग्री अपलोड करें या उम्मीदवार तैयार करें, फिर केवल उन संपत्तियों को चिह्नित करें जो भविष्य की पीढ़ियों को संदर्भ के रूप में मार्गदर्शन करें।",
|
|
@@ -6206,6 +6261,12 @@ export const messagesByLocale = {
|
|
|
6206
6261
|
}),
|
|
6207
6262
|
"ar-SA": mergeMessages({
|
|
6208
6263
|
library: {
|
|
6264
|
+
allLibraries: "جميع المكتبات",
|
|
6265
|
+
noDrafts: "لا توجد مسودات بعد.",
|
|
6266
|
+
noMatchingDrafts: "لا توجد مسودات مطابقة.",
|
|
6267
|
+
recentDrafts: "المسودات الأخيرة",
|
|
6268
|
+
viewAllDrafts: "عرض جميع المسودات",
|
|
6269
|
+
draftAsset: "مسودة",
|
|
6209
6270
|
addAssets: "أضف الأصول",
|
|
6210
6271
|
addAssetsDescription:
|
|
6211
6272
|
"قم بتحميل المواد المصدرية أو قم بإنشاء مرشحين، ثم حدد فقط الأصول التي يجب أن توجه الأجيال القادمة كمراجع.",
|
|
@@ -9,6 +9,7 @@ import { IconPhoto, IconSparkles, IconVideo } from "@tabler/icons-react";
|
|
|
9
9
|
import { useEffect } from "react";
|
|
10
10
|
import { useNavigate, useParams } from "react-router";
|
|
11
11
|
|
|
12
|
+
import { RecentDraftsSection } from "@/components/create/RecentDraftsSection";
|
|
12
13
|
import { GenerationResults } from "@/components/generation/GenerationResults";
|
|
13
14
|
import { useImageModelMenu } from "@/hooks/use-image-model-menu";
|
|
14
15
|
import { ASSETS_CHAT_STORAGE_KEY } from "@/lib/chat";
|
|
@@ -122,6 +123,9 @@ export default function CreatePage() {
|
|
|
122
123
|
</button>
|
|
123
124
|
))}
|
|
124
125
|
</div>
|
|
126
|
+
<div className="mt-8 w-full text-left">
|
|
127
|
+
<RecentDraftsSection />
|
|
128
|
+
</div>
|
|
125
129
|
</div>
|
|
126
130
|
}
|
|
127
131
|
/>
|
|
@@ -102,16 +102,22 @@ import {
|
|
|
102
102
|
type VariantSlot,
|
|
103
103
|
} from "./brand-kits.$id";
|
|
104
104
|
|
|
105
|
-
type AssetTab = "all" | "generated" | "references";
|
|
105
|
+
type AssetTab = "all" | "generated" | "drafts" | "references";
|
|
106
106
|
|
|
107
107
|
function isGeneratedAsset(asset: Asset) {
|
|
108
108
|
const role = asset.role ?? "";
|
|
109
109
|
return role === "generated" || role === "active" || role === "candidate";
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
function isDraftAsset(asset: Asset) {
|
|
113
|
+
return asset.role === "generated" && asset.status === "candidate";
|
|
114
|
+
}
|
|
115
|
+
|
|
112
116
|
function assetMatchesTab(asset: Asset, tab: AssetTab) {
|
|
113
117
|
if (tab === "all") return true;
|
|
114
|
-
if (tab === "
|
|
118
|
+
if (tab === "drafts") return isDraftAsset(asset);
|
|
119
|
+
if (tab === "generated")
|
|
120
|
+
return isGeneratedAsset(asset) && !isDraftAsset(asset);
|
|
115
121
|
return !isGeneratedAsset(asset);
|
|
116
122
|
}
|
|
117
123
|
|
|
@@ -1957,12 +1963,29 @@ export function LibraryWorkspace({
|
|
|
1957
1963
|
|
|
1958
1964
|
export function AssetPickerSurface() {
|
|
1959
1965
|
const t = useT();
|
|
1960
|
-
const [searchParams] = useSearchParams();
|
|
1966
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
1961
1967
|
const searchParamsKey = searchParams.toString();
|
|
1968
|
+
const urlAssetTab = useMemo<AssetTab | null>(() => {
|
|
1969
|
+
const tab = new URLSearchParams(searchParamsKey).get("tab");
|
|
1970
|
+
return tab === "all" ||
|
|
1971
|
+
tab === "generated" ||
|
|
1972
|
+
tab === "drafts" ||
|
|
1973
|
+
tab === "references"
|
|
1974
|
+
? tab
|
|
1975
|
+
: null;
|
|
1976
|
+
}, [searchParamsKey]);
|
|
1977
|
+
// The active tab is the only host-irrelevant search param. Exclude it from the
|
|
1978
|
+
// host-config key so toggling tabs (which writes `?tab=`) doesn't retrigger the
|
|
1979
|
+
// effect that resets media type / query / library from the URL.
|
|
1980
|
+
const hostParamsKey = useMemo(() => {
|
|
1981
|
+
const params = new URLSearchParams(searchParamsKey);
|
|
1982
|
+
params.delete("tab");
|
|
1983
|
+
return params.toString();
|
|
1984
|
+
}, [searchParamsKey]);
|
|
1962
1985
|
const mcpChatBridgeActive =
|
|
1963
1986
|
searchParamsRequestPicker(searchParams) || isEmbedMcpChatBridgeActive();
|
|
1964
1987
|
const urlHostConfig = useMemo(() => {
|
|
1965
|
-
const params = new URLSearchParams(
|
|
1988
|
+
const params = new URLSearchParams(hostParamsKey);
|
|
1966
1989
|
return {
|
|
1967
1990
|
mediaType: normalizeMediaType(params.get("mediaType")),
|
|
1968
1991
|
prompt: params.get("prompt") ?? undefined,
|
|
@@ -1983,7 +2006,7 @@ export function AssetPickerSurface() {
|
|
|
1983
2006
|
),
|
|
1984
2007
|
autoGenerate: normalizeBoolean(params.get("autoGenerate")) ?? false,
|
|
1985
2008
|
} satisfies HostConfig;
|
|
1986
|
-
}, [
|
|
2009
|
+
}, [hostParamsKey]);
|
|
1987
2010
|
const bridgeRef = useRef<EmbeddedAppBridge | null>(null);
|
|
1988
2011
|
const embedded = useMemo(
|
|
1989
2012
|
() =>
|
|
@@ -2008,7 +2031,7 @@ export function AssetPickerSurface() {
|
|
|
2008
2031
|
);
|
|
2009
2032
|
const [presetId, setPresetId] = useState(() => hostConfig.presetId ?? "none");
|
|
2010
2033
|
const [count, setCount] = useState(() => hostConfig.count ?? 3);
|
|
2011
|
-
const [assetTab, setAssetTab] = useState<AssetTab>("all");
|
|
2034
|
+
const [assetTab, setAssetTab] = useState<AssetTab>(urlAssetTab ?? "all");
|
|
2012
2035
|
const [selectedLibraryId, setSelectedLibraryId] = useState(
|
|
2013
2036
|
() => hostConfig.libraryId ?? "",
|
|
2014
2037
|
);
|
|
@@ -2032,6 +2055,30 @@ export function AssetPickerSurface() {
|
|
|
2032
2055
|
setVisibleCandidateRunIds(urlHostConfig.candidateRunIds ?? []);
|
|
2033
2056
|
}, [urlHostConfig]);
|
|
2034
2057
|
|
|
2058
|
+
useEffect(() => {
|
|
2059
|
+
// Reset to "all" when the tab param is removed (e.g. back/forward nav)
|
|
2060
|
+
// since the component stays mounted across search-param changes.
|
|
2061
|
+
setAssetTab(urlAssetTab ?? "all");
|
|
2062
|
+
}, [urlAssetTab]);
|
|
2063
|
+
|
|
2064
|
+
const handleAssetTabChange = useCallback(
|
|
2065
|
+
(value: AssetTab) => {
|
|
2066
|
+
setAssetTab(value);
|
|
2067
|
+
// Keep the tab reflected in the URL so it survives refresh/share and
|
|
2068
|
+
// stays consistent with the `?tab=` deep link from the home page.
|
|
2069
|
+
setSearchParams(
|
|
2070
|
+
(prev) => {
|
|
2071
|
+
const next = new URLSearchParams(prev);
|
|
2072
|
+
if (value === "all") next.delete("tab");
|
|
2073
|
+
else next.set("tab", value);
|
|
2074
|
+
return next;
|
|
2075
|
+
},
|
|
2076
|
+
{ replace: true },
|
|
2077
|
+
);
|
|
2078
|
+
},
|
|
2079
|
+
[setSearchParams],
|
|
2080
|
+
);
|
|
2081
|
+
|
|
2035
2082
|
const librariesQuery = useActionQuery("list-libraries", {
|
|
2036
2083
|
compact: true,
|
|
2037
2084
|
} as any) as {
|
|
@@ -2116,23 +2163,54 @@ export function AssetPickerSurface() {
|
|
|
2116
2163
|
!selectedPreset &&
|
|
2117
2164
|
Boolean(waitingForPresetData);
|
|
2118
2165
|
const mediaLabel = mediaType === "video" ? "video" : "image";
|
|
2166
|
+
const viewingDrafts = assetTab === "drafts";
|
|
2167
|
+
// The standalone Library "Drafts" tab mirrors the home Recent Drafts section:
|
|
2168
|
+
// every unsaved draft across all accessible libraries, regardless of media
|
|
2169
|
+
// type. The embedded picker keeps its library + media-type scope so an
|
|
2170
|
+
// image-only picker never surfaces video drafts.
|
|
2171
|
+
const draftsGlobalView = viewingDrafts && !embedded;
|
|
2119
2172
|
const assetsParams = useMemo(
|
|
2120
2173
|
() => ({
|
|
2121
2174
|
libraryId: selectedLibraryId,
|
|
2122
2175
|
mediaType,
|
|
2176
|
+
// Drafts are exactly generated candidates — filter them server-side
|
|
2177
|
+
// instead of fetching the whole library and filtering on the client.
|
|
2178
|
+
role: viewingDrafts ? "generated" : undefined,
|
|
2179
|
+
status: viewingDrafts ? "candidate" : undefined,
|
|
2123
2180
|
query: query.trim() || undefined,
|
|
2124
2181
|
includeCandidates:
|
|
2125
|
-
|
|
2182
|
+
viewingDrafts ||
|
|
2183
|
+
(mediaType === "image" && visibleCandidateRunIds.length > 0),
|
|
2184
|
+
// The Drafts tab shows every unsaved draft, not just the latest run batch.
|
|
2126
2185
|
candidateRunIds:
|
|
2127
|
-
visibleCandidateRunIds.length > 0
|
|
2186
|
+
!viewingDrafts && visibleCandidateRunIds.length > 0
|
|
2187
|
+
? visibleCandidateRunIds
|
|
2188
|
+
: undefined,
|
|
2128
2189
|
}),
|
|
2129
|
-
[
|
|
2190
|
+
[
|
|
2191
|
+
viewingDrafts,
|
|
2192
|
+
mediaType,
|
|
2193
|
+
query,
|
|
2194
|
+
selectedLibraryId,
|
|
2195
|
+
visibleCandidateRunIds,
|
|
2196
|
+
],
|
|
2130
2197
|
);
|
|
2131
2198
|
const { data: assetData, isLoading: assetsLoading } = useActionQuery(
|
|
2132
2199
|
"list-assets",
|
|
2133
2200
|
assetsParams as any,
|
|
2134
|
-
{
|
|
2201
|
+
{
|
|
2202
|
+
enabled:
|
|
2203
|
+
Boolean(selectedLibraryId) && !usingStarterLibrary && !draftsGlobalView,
|
|
2204
|
+
} as any,
|
|
2135
2205
|
) as { data?: { assets?: Asset[] }; isLoading: boolean };
|
|
2206
|
+
const { data: globalDraftsData, isLoading: globalDraftsLoading } =
|
|
2207
|
+
useActionQuery(
|
|
2208
|
+
"list-draft-assets",
|
|
2209
|
+
{ limit: 500 } as any,
|
|
2210
|
+
{
|
|
2211
|
+
enabled: draftsGlobalView,
|
|
2212
|
+
} as any,
|
|
2213
|
+
) as { data?: { assets?: Asset[] }; isLoading: boolean };
|
|
2136
2214
|
const starterAssets: Asset[] = useMemo(
|
|
2137
2215
|
() =>
|
|
2138
2216
|
STARTER_PRESET.referenceImages.map((reference) => ({
|
|
@@ -2159,11 +2237,23 @@ export function AssetPickerSurface() {
|
|
|
2159
2237
|
.some((value) => String(value).toLowerCase().includes(needle)),
|
|
2160
2238
|
);
|
|
2161
2239
|
}, [query, starterAssets]);
|
|
2162
|
-
const
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2240
|
+
const globalDrafts = useMemo(() => {
|
|
2241
|
+
const drafts = globalDraftsData?.assets ?? [];
|
|
2242
|
+
const needle = query.trim().toLowerCase();
|
|
2243
|
+
if (!needle) return drafts;
|
|
2244
|
+
return drafts.filter((asset) =>
|
|
2245
|
+
[asset.title, asset.description, asset.prompt]
|
|
2246
|
+
.filter(Boolean)
|
|
2247
|
+
.some((value) => String(value).toLowerCase().includes(needle)),
|
|
2248
|
+
);
|
|
2249
|
+
}, [globalDraftsData, query]);
|
|
2250
|
+
const allAssets = draftsGlobalView
|
|
2251
|
+
? globalDrafts
|
|
2252
|
+
: usingStarterLibrary
|
|
2253
|
+
? mediaType === "image"
|
|
2254
|
+
? visibleStarterAssets
|
|
2255
|
+
: []
|
|
2256
|
+
: (assetData?.assets ?? []);
|
|
2167
2257
|
const currentLibrary = useMemo(
|
|
2168
2258
|
() =>
|
|
2169
2259
|
displayLibraries.find((library) => library.id === selectedLibraryId) ??
|
|
@@ -2174,6 +2264,7 @@ export function AssetPickerSurface() {
|
|
|
2174
2264
|
() => allAssets.filter((asset) => assetMatchesTab(asset, assetTab)),
|
|
2175
2265
|
[allAssets, assetTab],
|
|
2176
2266
|
);
|
|
2267
|
+
const listLoading = draftsGlobalView ? globalDraftsLoading : assetsLoading;
|
|
2177
2268
|
const [previewAsset, setPreviewAsset] = useState<Asset | null>(null);
|
|
2178
2269
|
const [standaloneSelection, setStandaloneSelection] = useState<ReturnType<
|
|
2179
2270
|
typeof assetPayload
|
|
@@ -2845,27 +2936,35 @@ export function AssetPickerSurface() {
|
|
|
2845
2936
|
{displayLibraries.length > 0 && (
|
|
2846
2937
|
<div className="mb-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
|
2847
2938
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-center">
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2939
|
+
{draftsGlobalView ? (
|
|
2940
|
+
<div className="flex h-9 items-center rounded-md border border-border/70 bg-background px-3 text-sm text-muted-foreground sm:w-48">
|
|
2941
|
+
{t("library.allLibraries")}
|
|
2942
|
+
</div>
|
|
2943
|
+
) : (
|
|
2944
|
+
<Select
|
|
2945
|
+
value={selectedLibraryId}
|
|
2946
|
+
onValueChange={setSelectedLibraryId}
|
|
2947
|
+
>
|
|
2948
|
+
<SelectTrigger className="h-9 w-full border-border/70 bg-background sm:w-48">
|
|
2949
|
+
<SelectValue placeholder={t("library.library")} />
|
|
2950
|
+
</SelectTrigger>
|
|
2951
|
+
<SelectContent>
|
|
2952
|
+
<SelectGroup>
|
|
2953
|
+
{displayLibraries.map((library) => (
|
|
2954
|
+
<SelectItem key={library.id} value={library.id}>
|
|
2955
|
+
{library.title}
|
|
2956
|
+
</SelectItem>
|
|
2957
|
+
))}
|
|
2958
|
+
</SelectGroup>
|
|
2959
|
+
</SelectContent>
|
|
2960
|
+
</Select>
|
|
2961
|
+
)}
|
|
2865
2962
|
{selectedLibraryId && (
|
|
2866
2963
|
<Tabs
|
|
2867
2964
|
value={assetTab}
|
|
2868
|
-
onValueChange={(value) =>
|
|
2965
|
+
onValueChange={(value) =>
|
|
2966
|
+
handleAssetTabChange(value as AssetTab)
|
|
2967
|
+
}
|
|
2869
2968
|
>
|
|
2870
2969
|
<TabsList>
|
|
2871
2970
|
<TabsTrigger value="all">
|
|
@@ -2874,6 +2973,9 @@ export function AssetPickerSurface() {
|
|
|
2874
2973
|
<TabsTrigger value="generated">
|
|
2875
2974
|
{t("library.generated")}
|
|
2876
2975
|
</TabsTrigger>
|
|
2976
|
+
<TabsTrigger value="drafts">
|
|
2977
|
+
{t("library.drafts")}
|
|
2978
|
+
</TabsTrigger>
|
|
2877
2979
|
<TabsTrigger value="references">
|
|
2878
2980
|
{t("library.references")}
|
|
2879
2981
|
</TabsTrigger>
|
|
@@ -2897,6 +2999,7 @@ export function AssetPickerSurface() {
|
|
|
2897
2999
|
{mediaType === "image" &&
|
|
2898
3000
|
selectedLibraryId &&
|
|
2899
3001
|
!usingStarterLibrary &&
|
|
3002
|
+
!viewingDrafts &&
|
|
2900
3003
|
pickerVariantScopeId && (
|
|
2901
3004
|
<LibraryCandidateStage
|
|
2902
3005
|
activeLibraryId={selectedLibraryId}
|
|
@@ -2914,7 +3017,7 @@ export function AssetPickerSurface() {
|
|
|
2914
3017
|
</div>
|
|
2915
3018
|
)}
|
|
2916
3019
|
|
|
2917
|
-
{selectedLibraryId &&
|
|
3020
|
+
{selectedLibraryId && listLoading && (
|
|
2918
3021
|
<div className="assets-library-dense-grid grid grid-cols-2 gap-3">
|
|
2919
3022
|
{Array.from({ length: 8 }).map((_, index) => (
|
|
2920
3023
|
<Skeleton key={index} className="aspect-square rounded-md" />
|
|
@@ -2922,12 +3025,16 @@ export function AssetPickerSurface() {
|
|
|
2922
3025
|
</div>
|
|
2923
3026
|
)}
|
|
2924
3027
|
|
|
2925
|
-
{selectedLibraryId && !
|
|
3028
|
+
{selectedLibraryId && !listLoading && assets.length === 0 && (
|
|
2926
3029
|
<div className="flex h-full items-center justify-center text-center">
|
|
2927
3030
|
<div className="max-w-sm text-sm text-muted-foreground">
|
|
2928
|
-
{
|
|
2929
|
-
?
|
|
2930
|
-
|
|
3031
|
+
{draftsGlobalView
|
|
3032
|
+
? query
|
|
3033
|
+
? t("library.noMatchingDrafts")
|
|
3034
|
+
: t("library.noDrafts")
|
|
3035
|
+
: query
|
|
3036
|
+
? t("library.noMatchingLibraryAssets", { mediaLabel })
|
|
3037
|
+
: t("library.noAssetsInLibrary", { mediaLabel })}
|
|
2931
3038
|
</div>
|
|
2932
3039
|
</div>
|
|
2933
3040
|
)}
|