@agent-native/core 0.106.2 → 0.107.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 +2 -2
- package/corpus/core/CHANGELOG.md +19 -0
- package/corpus/core/docs/content/external-agents.mdx +8 -0
- package/corpus/core/docs/content/integrations.mdx +597 -0
- package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +7 -0
- package/corpus/core/docs/content/locales/ar-SA/mcp-clients.mdx +19 -1
- package/corpus/core/docs/content/locales/ar-SA/mcp-protocol.mdx +7 -0
- package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +9 -0
- package/corpus/core/docs/content/locales/de-DE/mcp-clients.mdx +22 -1
- package/corpus/core/docs/content/locales/de-DE/mcp-protocol.mdx +9 -0
- package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +9 -0
- package/corpus/core/docs/content/locales/es-ES/mcp-clients.mdx +23 -1
- package/corpus/core/docs/content/locales/es-ES/mcp-protocol.mdx +9 -0
- package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +9 -0
- package/corpus/core/docs/content/locales/fr-FR/mcp-clients.mdx +23 -1
- package/corpus/core/docs/content/locales/fr-FR/mcp-protocol.mdx +9 -0
- package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +8 -0
- package/corpus/core/docs/content/locales/hi-IN/mcp-clients.mdx +22 -1
- package/corpus/core/docs/content/locales/hi-IN/mcp-protocol.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +8 -0
- package/corpus/core/docs/content/locales/ja-JP/mcp-clients.mdx +21 -1
- package/corpus/core/docs/content/locales/ja-JP/mcp-protocol.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +8 -0
- package/corpus/core/docs/content/locales/ko-KR/mcp-clients.mdx +20 -1
- package/corpus/core/docs/content/locales/ko-KR/mcp-protocol.mdx +8 -0
- package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +9 -0
- package/corpus/core/docs/content/locales/pt-BR/mcp-clients.mdx +22 -1
- package/corpus/core/docs/content/locales/pt-BR/mcp-protocol.mdx +9 -0
- package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-CN/mcp-clients.mdx +17 -1
- package/corpus/core/docs/content/locales/zh-CN/mcp-protocol.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +6 -0
- package/corpus/core/docs/content/locales/zh-TW/mcp-clients.mdx +17 -1
- package/corpus/core/docs/content/locales/zh-TW/mcp-protocol.mdx +6 -0
- package/corpus/core/docs/content/mcp-clients.mdx +51 -1
- package/corpus/core/docs/content/mcp-protocol.mdx +8 -0
- package/corpus/core/docs/content/organizations-teams-permissions.mdx +413 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AssistantChat.tsx +13 -1
- package/corpus/core/src/client/chat/message-components.tsx +41 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +45 -8
- package/corpus/core/src/client/integrations/IntegrationsPanel.tsx +30 -11
- package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +240 -0
- package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +159 -40
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +433 -4
- package/corpus/core/src/client/resources/mcp-integration-logos.ts +108 -0
- package/corpus/core/src/deploy/build.ts +32 -0
- package/corpus/core/src/extensions/html-shell.ts +33 -1
- package/corpus/core/src/ingestion/office.ts +1 -2
- package/corpus/core/src/ingestion/pptx.ts +2 -4
- package/corpus/core/src/localization/default-messages.ts +126 -1
- package/corpus/core/src/mcp/actions/call-mcp-tool.ts +1 -0
- package/corpus/core/src/mcp/builtin-tools.ts +115 -10
- package/corpus/core/src/server/index.ts +4 -0
- package/corpus/core/src/server/org-admin.ts +28 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +9 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/references/api.md +31 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +9 -0
- package/corpus/templates/analytics/.agents/skills/creative-context/SKILL.md +64 -0
- package/corpus/templates/analytics/AGENTS.md +5 -0
- package/corpus/templates/analytics/actions/clone-creative-context-dashboard.ts +86 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +2 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/analytics/app/i18n-data.ts +1 -0
- package/corpus/templates/analytics/app/pages/Ask.tsx +8 -4
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +59 -0
- package/corpus/templates/analytics/app/routes/agent.tsx +7 -1
- package/corpus/templates/analytics/changelog/2026-07-17-library-now-flags-published-dashboards-with-newer-versions-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-resources-can-be-added-to-creative-context-from-their-action.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-you-can-add-exact-approved-artifact-versions-to-governed-cre.md +6 -0
- package/corpus/templates/analytics/package.json +1 -0
- package/corpus/templates/analytics/server/lib/native-creative-context.ts +158 -0
- package/corpus/templates/analytics/server/plugins/creative-context.ts +10 -0
- package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +12 -3
- package/corpus/templates/assets/AGENTS.md +5 -0
- package/corpus/templates/assets/actions/clone-creative-context-asset.ts +74 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +308 -178
- package/corpus/templates/assets/app/routes/library.tsx +5 -11
- package/corpus/templates/assets/changelog/2026-07-17-library-now-flags-published-assets-with-newer-versions-and-l.md +6 -0
- package/corpus/templates/assets/changelog/2026-07-17-you-can-add-exact-approved-artifact-versions-to-governed-cre.md +6 -0
- package/corpus/templates/assets/server/lib/native-creative-context.ts +198 -0
- package/corpus/templates/assets/server/plugins/creative-context.ts +4 -0
- package/corpus/templates/brain/actions/provider-api-request.ts +1 -0
- package/corpus/templates/calendar/actions/provider-api-request.ts +1 -0
- package/corpus/templates/clips/actions/get-recording-insights.ts +7 -4
- package/corpus/templates/clips/actions/list-recordings.ts +48 -0
- package/corpus/templates/clips/actions/list-viewers.ts +2 -1
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +3 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +1 -3
- package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +11 -6
- package/corpus/templates/clips/app/hooks/use-view-tracking.ts +6 -1
- package/corpus/templates/clips/app/lib/ffmpeg-export.ts +4 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -3
- package/corpus/templates/clips/changelog/2026-07-17-dictation-keeps-sentence-spacing-and-no-longer-crashes-when-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-shared-clips-now-preserve-editor-access-and-show-editor-insi.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-stitching-clips-no-longer-fails-when-editor-media-metadata-i.md +6 -0
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +14 -8
- package/corpus/templates/clips/shared/view-analytics.ts +4 -0
- package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +12 -3
- package/corpus/templates/content/AGENTS.md +5 -0
- package/corpus/templates/content/actions/clone-creative-context-document.ts +61 -0
- package/corpus/templates/content/actions/provider-api-request.ts +1 -0
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +21 -0
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +29 -0
- package/corpus/templates/content/changelog/2026-07-17-library-now-flags-published-documents-with-newer-versions-an.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-resources-can-be-added-to-creative-context-from-their-action.md +6 -0
- package/corpus/templates/content/changelog/2026-07-17-you-can-add-exact-approved-artifact-versions-to-governed-cre.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +1 -0
- package/corpus/templates/content/server/lib/native-creative-context.ts +191 -0
- package/corpus/templates/content/server/plugins/creative-context.ts +8 -1
- package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -3
- package/corpus/templates/design/AGENTS.md +5 -0
- package/corpus/templates/design/actions/clone-creative-context-design-native.ts +111 -0
- package/corpus/templates/design/actions/provider-api-request.ts +1 -0
- package/corpus/templates/design/app/pages/Index.tsx +44 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +1 -0
- package/corpus/templates/design/changelog/2026-07-17-library-now-flags-published-designs-with-newer-versions-and-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-17-resources-can-be-added-to-creative-context-from-their-action.md +6 -0
- package/corpus/templates/design/changelog/2026-07-17-you-can-add-exact-approved-artifact-versions-to-governed-cre.md +6 -0
- package/corpus/templates/design/server/lib/native-creative-context.ts +265 -0
- package/corpus/templates/design/server/plugins/creative-context.ts +8 -1
- package/corpus/templates/dispatch/actions/provider-api-request.ts +1 -0
- package/corpus/templates/mail/actions/provider-api-request.ts +1 -0
- package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +11 -3
- package/corpus/templates/slides/AGENTS.md +5 -0
- package/corpus/templates/slides/actions/clone-creative-context-deck.ts +96 -0
- package/corpus/templates/slides/actions/extract-pdf.ts +3 -2
- package/corpus/templates/slides/actions/import-file.ts +3 -2
- package/corpus/templates/slides/actions/provider-api-request.ts +1 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +27 -0
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +21 -0
- package/corpus/templates/slides/changelog/2026-07-17-library-now-flags-published-decks-with-newer-versions-and-le.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-17-pdf-and-powerpoint-imports-now-work-reliably-in-hosted-decks.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-17-resources-can-be-added-to-creative-context-from-their-action.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-17-you-can-add-exact-approved-artifact-versions-to-governed-cre.md +6 -0
- package/corpus/templates/slides/server/lib/native-creative-context.ts +288 -0
- package/corpus/templates/slides/server/plugins/creative-context.ts +4 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +8 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +35 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +7 -0
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +37 -8
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -2
- package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
- package/dist/client/resources/McpConnectionSuggestion.d.ts +9 -0
- package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +115 -0
- package/dist/client/resources/McpConnectionSuggestion.js.map +1 -0
- package/dist/client/resources/McpIntegrationDialog.d.ts +2 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
- package/dist/client/resources/McpIntegrationDialog.js +48 -20
- package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +9 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +387 -4
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/resources/mcp-integration-logos.d.ts +2 -0
- package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -0
- package/dist/client/resources/mcp-integration-logos.js +109 -0
- package/dist/client/resources/mcp-integration-logos.js.map +1 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +23 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/extensions/html-shell.d.ts.map +1 -1
- package/dist/extensions/html-shell.js +33 -1
- package/dist/extensions/html-shell.js.map +1 -1
- package/dist/ingestion/office.d.ts.map +1 -1
- package/dist/ingestion/office.js +1 -2
- package/dist/ingestion/office.js.map +1 -1
- package/dist/ingestion/pptx.js +2 -4
- package/dist/ingestion/pptx.js.map +1 -1
- package/dist/localization/default-messages.d.ts +98 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +99 -1
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/actions/call-mcp-tool.js +1 -0
- package/dist/mcp/actions/call-mcp-tool.js.map +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +87 -6
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/org-admin.d.ts +3 -0
- package/dist/server/org-admin.d.ts.map +1 -0
- package/dist/server/org-admin.js +24 -0
- package/dist/server/org-admin.js.map +1 -0
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +9 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +31 -0
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +9 -0
- package/docs/content/external-agents.mdx +8 -0
- package/docs/content/integrations.mdx +597 -0
- package/docs/content/locales/ar-SA/external-agents.mdx +7 -0
- package/docs/content/locales/ar-SA/mcp-clients.mdx +19 -1
- package/docs/content/locales/ar-SA/mcp-protocol.mdx +7 -0
- package/docs/content/locales/de-DE/external-agents.mdx +9 -0
- package/docs/content/locales/de-DE/mcp-clients.mdx +22 -1
- package/docs/content/locales/de-DE/mcp-protocol.mdx +9 -0
- package/docs/content/locales/es-ES/external-agents.mdx +9 -0
- package/docs/content/locales/es-ES/mcp-clients.mdx +23 -1
- package/docs/content/locales/es-ES/mcp-protocol.mdx +9 -0
- package/docs/content/locales/fr-FR/external-agents.mdx +9 -0
- package/docs/content/locales/fr-FR/mcp-clients.mdx +23 -1
- package/docs/content/locales/fr-FR/mcp-protocol.mdx +9 -0
- package/docs/content/locales/hi-IN/external-agents.mdx +8 -0
- package/docs/content/locales/hi-IN/mcp-clients.mdx +22 -1
- package/docs/content/locales/hi-IN/mcp-protocol.mdx +8 -0
- package/docs/content/locales/ja-JP/external-agents.mdx +8 -0
- package/docs/content/locales/ja-JP/mcp-clients.mdx +21 -1
- package/docs/content/locales/ja-JP/mcp-protocol.mdx +8 -0
- package/docs/content/locales/ko-KR/external-agents.mdx +8 -0
- package/docs/content/locales/ko-KR/mcp-clients.mdx +20 -1
- package/docs/content/locales/ko-KR/mcp-protocol.mdx +8 -0
- package/docs/content/locales/pt-BR/external-agents.mdx +9 -0
- package/docs/content/locales/pt-BR/mcp-clients.mdx +22 -1
- package/docs/content/locales/pt-BR/mcp-protocol.mdx +9 -0
- package/docs/content/locales/zh-CN/external-agents.mdx +6 -0
- package/docs/content/locales/zh-CN/mcp-clients.mdx +17 -1
- package/docs/content/locales/zh-CN/mcp-protocol.mdx +6 -0
- package/docs/content/locales/zh-TW/external-agents.mdx +6 -0
- package/docs/content/locales/zh-TW/mcp-clients.mdx +17 -1
- package/docs/content/locales/zh-TW/mcp-protocol.mdx +6 -0
- package/docs/content/mcp-clients.mdx +51 -1
- package/docs/content/mcp-protocol.mdx +8 -0
- package/docs/content/organizations-teams-permissions.mdx +413 -0
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +9 -0
- package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +31 -0
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +9 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { defineAction } from "@agent-native/core";
|
|
4
|
+
import {
|
|
5
|
+
readPrivateBlob,
|
|
6
|
+
type PrivateBlobHandle,
|
|
7
|
+
} from "@agent-native/core/private-blob";
|
|
8
|
+
import { resolveNativeContextCloneReference } from "@agent-native/creative-context/server";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
import createDocument from "./create-document.js";
|
|
12
|
+
|
|
13
|
+
export default defineAction({
|
|
14
|
+
description:
|
|
15
|
+
"Clone one exact governed Markdown document without returning its private source payload.",
|
|
16
|
+
schema: z.object({
|
|
17
|
+
contextId: z.string(),
|
|
18
|
+
artifactKey: z.string(),
|
|
19
|
+
resourceId: z.string(),
|
|
20
|
+
expectedUpdatedAt: z.string().optional(),
|
|
21
|
+
title: z.string().optional(),
|
|
22
|
+
parentId: z.string().optional(),
|
|
23
|
+
}),
|
|
24
|
+
publicAgent: { expose: true, readOnly: false, requiresAuth: true },
|
|
25
|
+
run: async (args) => {
|
|
26
|
+
const reference = await resolveNativeContextCloneReference({
|
|
27
|
+
appId: "content",
|
|
28
|
+
resourceType: "document",
|
|
29
|
+
resourceId: args.resourceId,
|
|
30
|
+
expectedUpdatedAt: args.expectedUpdatedAt,
|
|
31
|
+
contextId: args.contextId,
|
|
32
|
+
artifactKey: args.artifactKey,
|
|
33
|
+
});
|
|
34
|
+
const raw = await readPrivateBlob(
|
|
35
|
+
reference.cloneHandle as PrivateBlobHandle,
|
|
36
|
+
);
|
|
37
|
+
const content = Buffer.from(raw.data).toString("utf8");
|
|
38
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
39
|
+
if (
|
|
40
|
+
raw.metadata?.appId !== "content" ||
|
|
41
|
+
raw.metadata?.resourceType !== "document" ||
|
|
42
|
+
raw.metadata?.resourceId !== args.resourceId ||
|
|
43
|
+
raw.metadata?.contentHash !== hash
|
|
44
|
+
)
|
|
45
|
+
throw new Error(
|
|
46
|
+
"Governed document clone payload failed integrity verification.",
|
|
47
|
+
);
|
|
48
|
+
const result = await createDocument.run({
|
|
49
|
+
title: args.title?.trim() || "Context document",
|
|
50
|
+
content,
|
|
51
|
+
...(args.parentId ? { parentId: args.parentId } : {}),
|
|
52
|
+
});
|
|
53
|
+
if (!result?.id) throw new Error("Document clone did not persist.");
|
|
54
|
+
return {
|
|
55
|
+
id: result.id,
|
|
56
|
+
title: result.title,
|
|
57
|
+
urlPath: result.urlPath,
|
|
58
|
+
clonedExactVersion: reference.publishedItemVersionId,
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type CollabUser,
|
|
8
8
|
} from "@agent-native/core/client";
|
|
9
9
|
import { ShareButton } from "@agent-native/core/client";
|
|
10
|
+
import { CreativeContextShareTab } from "@agent-native/creative-context/client";
|
|
10
11
|
import type { DocumentSourceInfo } from "@shared/api";
|
|
11
12
|
import {
|
|
12
13
|
IconArrowBarDown,
|
|
@@ -711,6 +712,26 @@ export function DocumentToolbar({
|
|
|
711
712
|
onCheckedChange: handleHideFromSearchChange,
|
|
712
713
|
}}
|
|
713
714
|
variant="compact"
|
|
715
|
+
shareTabs={{
|
|
716
|
+
tabs: [
|
|
717
|
+
{
|
|
718
|
+
value: "context",
|
|
719
|
+
label: "Context",
|
|
720
|
+
content: (
|
|
721
|
+
<CreativeContextShareTab
|
|
722
|
+
resource={{
|
|
723
|
+
appId: "content",
|
|
724
|
+
resourceType: "document",
|
|
725
|
+
resourceId: documentId,
|
|
726
|
+
title: documentTitle || "Untitled",
|
|
727
|
+
updatedAt: documentUpdatedAt ?? undefined,
|
|
728
|
+
preview: { kind: "document", label: "Document" },
|
|
729
|
+
}}
|
|
730
|
+
/>
|
|
731
|
+
),
|
|
732
|
+
},
|
|
733
|
+
],
|
|
734
|
+
}}
|
|
714
735
|
/>
|
|
715
736
|
|
|
716
737
|
<VersionHistoryPanel
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client";
|
|
2
|
+
import { CreativeContextShareSheet } from "@agent-native/creative-context/client";
|
|
2
3
|
import {
|
|
3
4
|
SortableContext,
|
|
4
5
|
useSortable,
|
|
@@ -114,6 +115,7 @@ export function DocumentTreeItem({
|
|
|
114
115
|
const hasMenuActions = canEdit || canManage;
|
|
115
116
|
const canCreateChild = canEdit && !isLocalFileNode;
|
|
116
117
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
118
|
+
const [contextSheetOpen, setContextSheetOpen] = useState(false);
|
|
117
119
|
const indent = depth * 12 + 12;
|
|
118
120
|
const rowWidth =
|
|
119
121
|
sidebarWidth === undefined ? undefined : Math.max(0, sidebarWidth - 8);
|
|
@@ -250,6 +252,18 @@ export function DocumentTreeItem({
|
|
|
250
252
|
</DropdownMenuItem>
|
|
251
253
|
)}
|
|
252
254
|
{canEdit && canManage && <DropdownMenuSeparator />}
|
|
255
|
+
{canEdit && !isLocalFileNode && (
|
|
256
|
+
<DropdownMenuItem
|
|
257
|
+
onSelect={(event) => {
|
|
258
|
+
event.preventDefault();
|
|
259
|
+
event.stopPropagation();
|
|
260
|
+
setContextSheetOpen(true);
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
<IconPlus size={14} className="me-2" />
|
|
264
|
+
{t("creativeContext.addToContext" /* i18n-key-ignore */)}
|
|
265
|
+
</DropdownMenuItem>
|
|
266
|
+
)}
|
|
253
267
|
{canManage && (
|
|
254
268
|
<DropdownMenuItem
|
|
255
269
|
className="text-destructive"
|
|
@@ -310,6 +324,21 @@ export function DocumentTreeItem({
|
|
|
310
324
|
</div>
|
|
311
325
|
</div>
|
|
312
326
|
|
|
327
|
+
<CreativeContextShareSheet
|
|
328
|
+
open={contextSheetOpen}
|
|
329
|
+
onOpenChange={setContextSheetOpen}
|
|
330
|
+
resource={{
|
|
331
|
+
appId: "content",
|
|
332
|
+
resourceType: "document",
|
|
333
|
+
resourceId: node.id,
|
|
334
|
+
title: node.title || "Untitled",
|
|
335
|
+
updatedAt: node.updatedAt,
|
|
336
|
+
visibility: node.visibility,
|
|
337
|
+
preview: { kind: "document", label: "Document" },
|
|
338
|
+
}}
|
|
339
|
+
canManage={canManage}
|
|
340
|
+
/>
|
|
341
|
+
|
|
313
342
|
{hasChildren && expanded && (
|
|
314
343
|
<SortableContext
|
|
315
344
|
items={node.children.map((child) => child.id)}
|
|
@@ -20,7 +20,7 @@ This generated matrix tracks whether high-value Content UI operations use the sa
|
|
|
20
20
|
| sharing.document-discoverability-and-export | sharing | Share, hide from search, export, and reveal documents | action-backed | `export-document`, `reveal-local-source-file`, `set-document-discoverability`, `share-local-file-document` | `app/components/editor/DocumentToolbar.tsx`, `app/hooks/use-documents.ts` | Search discoverability, shareable copies, exports, and OS reveal requests are managed through Content actions. | - | - | P0 | covered | `actions/_local-file-documents.test.ts` | `local-file-source-truth` | - |
|
|
21
21
|
| sharing.os-reveal-local-source | sharing | Reveal a local source file in the system file manager | host-only | `reveal-local-source-file` | `app/components/editor/DocumentToolbar.tsx`, `actions/reveal-local-source-file.ts` | - | OS reveal depends on trusted local host capabilities and should not spend agent tool surface or imply portable hosted behavior. | - | P2 | seeded | - | - | Local folder exception/docs PR |
|
|
22
22
|
| sidebar.chrome-state | sidebar | Collapse sections and resize the sidebar | client-only-ephemeral | - | `app/components/sidebar/DocumentSidebar.tsx`, `app/components/layout/Layout.tsx` | - | - | - | P2 | none | - | - | - |
|
|
23
|
-
| sidebar.document-tree-crud | sidebar | Create, delete, move, favorite, list, search, and open pages | action-backed | `create-document`, `delete-document`, `get-document`, `list-documents`, `move-document`, `search-documents`, `update-document`
|
|
23
|
+
| sidebar.document-tree-crud | sidebar | Create, delete, move, favorite, list, search, and open pages | action-backed | `create-document`, `clone-creative-context-document`, `delete-document`, `get-document`, `list-documents`, `move-document`, `search-documents`, `update-document` | `app/components/sidebar/DocumentSidebar.tsx`, `app/components/sidebar/DocumentTreeItem.tsx`, `app/hooks/use-documents.ts` | Document tree rows and document metadata are created, updated, deleted, moved, searched, or read. | - | - | P0 | covered | `actions/content-database-lifecycle.db.test.ts`, `actions/_local-file-documents.test.ts` | `document-search-edit` | - |
|
|
24
24
|
| sidebar.navigation-and-screen-context | sidebar | Navigate between documents and expose current screen context | action-equivalent | `navigate`, `view-screen` | `app/components/sidebar/DocumentSidebar.tsx`, `actions/navigate.ts`, `actions/view-screen.ts` | Application navigation state is updated or read so the agent can reason about the user's current page/view. | Human navigation is router-local, while agent navigation/screen inspection uses application-state actions to produce the same workspace orientation effect. | - | P1 | seeded | - | - | - |
|
|
25
25
|
| source-sync.builder-body-hydration-worker | source-sync | Process queued Builder CMS body hydration work | action-backed | `process-builder-body-hydration` | `app/components/editor/DocumentEditor.tsx`, `app/components/editor/database/DatabaseView.tsx`, `app/hooks/use-content-database.ts` | Queued Builder body hydration entries are processed into readable Content document/database body state. | This action is intentionally hidden from the model with agentTool: false because it is an internal bounded queue worker; agents should use source refresh, review, and execution actions rather than manually driving hydration internals. | - | P0 | covered | `actions/_database-source-utils.test.ts` | - | - |
|
|
26
26
|
| source-sync.builder-cms-review-and-write-gates | source-sync | Review, stage, validate, cancel, and execute Builder CMS source writes | action-backed | `cancel-prepared-builder-source-update`, `execute-builder-source-batch`, `execute-builder-source-execution`, `prepare-builder-source-execution`, `prepare-builder-source-review`, `preview-builder-source-review`, `review-content-database-source-change-set`, `set-content-database-source-write-mode`, `stage-builder-source-bulk-update`, `stage-builder-revision`, `validate-builder-source-execution` | `app/components/editor/DocumentDatabase.tsx`, `app/components/editor/database/DatabaseView.tsx`, `app/components/editor/database-sources/BuilderSourceReviewDialog.tsx` | Builder source write mode, staged reviews, pre-dispatch cancellations, validation records, and bounded execution records are created through guarded actions. | - | - | P0 | covered | `actions/builder-source-review-gates.db.test.ts`, `actions/cancel-prepared-builder-source-update.db.test.ts`, `actions/execute-builder-source-execution.test.ts`, `actions/stage-builder-source-bulk-update.db.test.ts` | `builder-source-review-readonly` | - |
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { putPrivateBlob } from "@agent-native/core/private-blob";
|
|
4
|
+
import { accessFilter, resolveAccess } from "@agent-native/core/sharing";
|
|
5
|
+
import type { NativeResourceCaptureAdapter } from "@agent-native/creative-context/server";
|
|
6
|
+
import { and, inArray } from "drizzle-orm";
|
|
7
|
+
|
|
8
|
+
import { flushOpenDocumentEditorToSql } from "../../actions/_document-flush.js";
|
|
9
|
+
import { getDb, schema } from "../db/index.js";
|
|
10
|
+
|
|
11
|
+
interface DocumentPreviewBlock {
|
|
12
|
+
kind: "heading" | "paragraph" | "bullet" | "quote" | "code";
|
|
13
|
+
text: string;
|
|
14
|
+
level?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function documentPreview(markdown: string) {
|
|
18
|
+
const lines = markdown.replace(/\r\n/g, "\n").split("\n");
|
|
19
|
+
const headings = lines
|
|
20
|
+
.filter((line) => /^#{1,6}\s+/.test(line))
|
|
21
|
+
.map((line) =>
|
|
22
|
+
line
|
|
23
|
+
.replace(/^#{1,6}\s+/, "")
|
|
24
|
+
.trim()
|
|
25
|
+
.slice(0, 160),
|
|
26
|
+
)
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.slice(0, 8);
|
|
29
|
+
const excerpt = lines
|
|
30
|
+
.filter((line) => !/^\s*(?:```|#{1,6}\s+)/.test(line))
|
|
31
|
+
.join(" ")
|
|
32
|
+
.replace(/\s+/g, " ")
|
|
33
|
+
.trim()
|
|
34
|
+
.slice(0, 1_500);
|
|
35
|
+
let inCode = false;
|
|
36
|
+
const blocks = lines
|
|
37
|
+
.slice(0, 240)
|
|
38
|
+
.flatMap<DocumentPreviewBlock>((rawLine) => {
|
|
39
|
+
const line = rawLine.trim();
|
|
40
|
+
if (/^```/.test(line)) {
|
|
41
|
+
inCode = !inCode;
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
if (!line) return [];
|
|
45
|
+
if (inCode) {
|
|
46
|
+
return [{ kind: "code" as const, text: rawLine.slice(0, 600) }];
|
|
47
|
+
}
|
|
48
|
+
const heading = /^(#{1,6})\s+(.+)$/.exec(line);
|
|
49
|
+
if (heading) {
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
kind: "heading" as const,
|
|
53
|
+
text: (heading[2] ?? "").slice(0, 300),
|
|
54
|
+
level: heading[1]?.length ?? 1,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
const bullet = /^(?:[-*+] |\d+[.)] )(.+)$/.exec(line);
|
|
59
|
+
if (bullet) {
|
|
60
|
+
return [
|
|
61
|
+
{ kind: "bullet" as const, text: (bullet[1] ?? "").slice(0, 600) },
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
if (line.startsWith(">")) {
|
|
65
|
+
return [
|
|
66
|
+
{ kind: "quote" as const, text: line.slice(1).trim().slice(0, 600) },
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
return [{ kind: "paragraph" as const, text: line.slice(0, 600) }];
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
type: "document" as const,
|
|
73
|
+
headings,
|
|
74
|
+
excerpt,
|
|
75
|
+
blocks: blocks.slice(0, 40),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const nativeDocumentCreativeContextAdapter: NativeResourceCaptureAdapter =
|
|
80
|
+
{
|
|
81
|
+
appId: "content",
|
|
82
|
+
resourceType: "document",
|
|
83
|
+
async listResourceVersions(resourceIds) {
|
|
84
|
+
if (!resourceIds.length) return [];
|
|
85
|
+
return getDb()
|
|
86
|
+
.select({
|
|
87
|
+
resourceId: schema.documents.id,
|
|
88
|
+
sourceModifiedAt: schema.documents.updatedAt,
|
|
89
|
+
})
|
|
90
|
+
.from(schema.documents)
|
|
91
|
+
.where(
|
|
92
|
+
and(
|
|
93
|
+
inArray(schema.documents.id, [...resourceIds]),
|
|
94
|
+
accessFilter(schema.documents, schema.documentShares),
|
|
95
|
+
),
|
|
96
|
+
);
|
|
97
|
+
},
|
|
98
|
+
async capture(reference) {
|
|
99
|
+
const access = await resolveAccess("document", reference.resourceId);
|
|
100
|
+
if (!access) throw new Error("Document not found");
|
|
101
|
+
const initial = access.resource as typeof schema.documents.$inferSelect;
|
|
102
|
+
if (
|
|
103
|
+
reference.expectedUpdatedAt &&
|
|
104
|
+
reference.expectedUpdatedAt !== initial.updatedAt
|
|
105
|
+
)
|
|
106
|
+
throw new Error(
|
|
107
|
+
"Document changed before it could be submitted to Context.",
|
|
108
|
+
);
|
|
109
|
+
await flushOpenDocumentEditorToSql({
|
|
110
|
+
documentId: initial.id,
|
|
111
|
+
ownerEmail: initial.ownerEmail ?? null,
|
|
112
|
+
});
|
|
113
|
+
const refreshed = await resolveAccess("document", initial.id);
|
|
114
|
+
if (!refreshed) throw new Error("Document not found");
|
|
115
|
+
const document =
|
|
116
|
+
refreshed.resource as typeof schema.documents.$inferSelect;
|
|
117
|
+
const contentHash = createHash("sha256")
|
|
118
|
+
.update(document.content)
|
|
119
|
+
.digest("hex");
|
|
120
|
+
const versionId = randomUUID();
|
|
121
|
+
await getDb().insert(schema.documentVersions).values({
|
|
122
|
+
id: versionId,
|
|
123
|
+
ownerEmail: document.ownerEmail,
|
|
124
|
+
documentId: document.id,
|
|
125
|
+
title: document.title,
|
|
126
|
+
content: document.content,
|
|
127
|
+
createdAt: new Date().toISOString(),
|
|
128
|
+
});
|
|
129
|
+
const handle = await putPrivateBlob({
|
|
130
|
+
data: Buffer.from(document.content),
|
|
131
|
+
filename: `${document.id}.md`,
|
|
132
|
+
mimeType: "text/markdown",
|
|
133
|
+
ownerEmail: document.ownerEmail,
|
|
134
|
+
key: `creative-context/content/${document.id}/${contentHash}.md`,
|
|
135
|
+
metadata: {
|
|
136
|
+
appId: "content",
|
|
137
|
+
resourceType: "document",
|
|
138
|
+
resourceId: document.id,
|
|
139
|
+
contentHash,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
if (!handle)
|
|
143
|
+
throw new Error(
|
|
144
|
+
"Private blob storage is required to submit a document to Context.",
|
|
145
|
+
);
|
|
146
|
+
return {
|
|
147
|
+
artifactKey: `content:document:${document.id}`,
|
|
148
|
+
source: {
|
|
149
|
+
name: "Content",
|
|
150
|
+
kind: "native-app",
|
|
151
|
+
externalRef: document.id,
|
|
152
|
+
access: {
|
|
153
|
+
visibility: document.visibility ?? "private",
|
|
154
|
+
canManage: refreshed.role === "owner" || refreshed.role === "admin",
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
items: [
|
|
158
|
+
{
|
|
159
|
+
externalId: `native:content:document:${document.id}`,
|
|
160
|
+
kind: "document",
|
|
161
|
+
title: document.title,
|
|
162
|
+
canonicalUrl: `/page/${document.id}`,
|
|
163
|
+
mimeType: "text/markdown",
|
|
164
|
+
content: document.content.slice(0, 40_000),
|
|
165
|
+
summary: document.description ?? "Immutable Markdown document.",
|
|
166
|
+
contentHash,
|
|
167
|
+
sourceModifiedAt: document.updatedAt,
|
|
168
|
+
sourceVersion: versionId,
|
|
169
|
+
metadata: { preview: documentPreview(document.content) },
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
privateMetadata: {
|
|
173
|
+
nativeResource: {
|
|
174
|
+
appId: "content",
|
|
175
|
+
resourceType: "document",
|
|
176
|
+
resourceId: document.id,
|
|
177
|
+
expectedUpdatedAt: reference.expectedUpdatedAt,
|
|
178
|
+
},
|
|
179
|
+
clone: {
|
|
180
|
+
handle,
|
|
181
|
+
appId: "content",
|
|
182
|
+
resourceType: "document",
|
|
183
|
+
resourceId: document.id,
|
|
184
|
+
contentHash,
|
|
185
|
+
sourceVersion: versionId,
|
|
186
|
+
updatedAt: document.updatedAt,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { registerOnboardingStep } from "@agent-native/core/onboarding";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
registerNativeResourceCaptureAdapter,
|
|
4
|
+
setupCreativeContext,
|
|
5
|
+
} from "@agent-native/creative-context/server";
|
|
3
6
|
import { listContextSources } from "@agent-native/creative-context/store";
|
|
4
7
|
|
|
8
|
+
import { nativeDocumentCreativeContextAdapter } from "../lib/native-creative-context.js";
|
|
9
|
+
|
|
5
10
|
registerOnboardingStep({
|
|
6
11
|
id: "creative-context-library",
|
|
7
12
|
order: 18,
|
|
@@ -28,4 +33,6 @@ registerOnboardingStep({
|
|
|
28
33
|
},
|
|
29
34
|
});
|
|
30
35
|
|
|
36
|
+
registerNativeResourceCaptureAdapter(nativeDocumentCreativeContextAdapter);
|
|
37
|
+
|
|
31
38
|
export default setupCreativeContext({ appId: "content" });
|
|
@@ -35,9 +35,11 @@ role cannot silently stand in for another:
|
|
|
35
35
|
|
|
36
36
|
1. Follow the user's explicit instructions and the object currently selected in
|
|
37
37
|
the app.
|
|
38
|
-
2. Read the `creative-context` application-state record. If
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
2. Read the `creative-context` application-state record. If `pinnedPackId` is
|
|
39
|
+
set, replay that immutable pack. Otherwise honor `selectedContextId`; when it
|
|
40
|
+
is unset, let retrieval use Default plus at most one app-bound or
|
|
41
|
+
semantically matching specialty context. `currentPackId` is the receipt from
|
|
42
|
+
the latest materialized generation, not a replacement for context selection.
|
|
41
43
|
3. Call `search-creative-context` with a narrow query for exact facts, visual
|
|
42
44
|
language, audience guidance, prior decisions, or reusable references.
|
|
43
45
|
4. Call `get-context-item` only for the specific search result versions
|
|
@@ -60,6 +62,7 @@ The single state key is `creative-context`:
|
|
|
60
62
|
```json
|
|
61
63
|
{
|
|
62
64
|
"contextMode": "auto",
|
|
65
|
+
"selectedContextId": null,
|
|
63
66
|
"currentPackId": null,
|
|
64
67
|
"pinnedPackId": null
|
|
65
68
|
}
|
|
@@ -114,3 +117,8 @@ If `nativeCode.content` is `null` and `oversized` is true, use the named
|
|
|
114
117
|
`get-context-item`, but the inline content is only the validated manifest shell.
|
|
115
118
|
Never concatenate a truncated fragment or use delimited `version.content` as
|
|
116
119
|
HTML.
|
|
120
|
+
|
|
121
|
+
For an app-created Design snapshot, use
|
|
122
|
+
`clone-creative-context-design-native` instead. That typed action resolves the
|
|
123
|
+
exact approved private file/Yjs payload and duplicates it through Design's
|
|
124
|
+
native path. Generic context actions must never receive or return that payload.
|
|
@@ -178,6 +178,11 @@ patterns live in `.agents/skills/`.
|
|
|
178
178
|
`.agents/skills/creative-context/SKILL.md`: explicit request and current
|
|
179
179
|
design first, then a pinned/current pack, then narrow library search. Respect
|
|
180
180
|
`creative-context.contextMode: "off"` without silently restoring a pack.
|
|
181
|
+
- To submit a design to a governed Creative Context, use the Context tab or
|
|
182
|
+
`manage-context-membership`; it captures one immutable live design snapshot.
|
|
183
|
+
Reuse only a returned opaque native clone reference through the Design clone action.
|
|
184
|
+
Use `operation="submit-latest"` with a Library membership id when its native
|
|
185
|
+
update status reports `update-available`.
|
|
181
186
|
- For reusable design-system setup from Figma, connected code/GitHub, local
|
|
182
187
|
code/design files, or optional `design.md`, use Builder-backed DSI indexing
|
|
183
188
|
through `index-design-system-with-builder` or the Design System Setup `.fig`
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import { defineAction } from "@agent-native/core";
|
|
4
|
+
import {
|
|
5
|
+
readPrivateBlob,
|
|
6
|
+
type PrivateBlobHandle,
|
|
7
|
+
} from "@agent-native/core/private-blob";
|
|
8
|
+
import { resolveNativeContextCloneReference } from "@agent-native/creative-context/server";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
import { mutateDesignData } from "../server/lib/design-data-mutation.js";
|
|
12
|
+
import { saveImportedDesignFiles } from "../server/lib/import-design-files.js";
|
|
13
|
+
import createDesign from "./create-design.js";
|
|
14
|
+
|
|
15
|
+
const payloadSchema = z.object({
|
|
16
|
+
designId: z.string(),
|
|
17
|
+
designData: z.string(),
|
|
18
|
+
files: z.array(
|
|
19
|
+
z.object({
|
|
20
|
+
filename: z.string(),
|
|
21
|
+
fileType: z.enum(["html", "css", "jsx", "asset"]),
|
|
22
|
+
content: z.string(),
|
|
23
|
+
}),
|
|
24
|
+
),
|
|
25
|
+
tweaks: z.unknown().optional(),
|
|
26
|
+
appliedTweaks: z.unknown().optional(),
|
|
27
|
+
resolvedCssVars: z.unknown().optional(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default defineAction({
|
|
31
|
+
description:
|
|
32
|
+
"Clone an exact governed Design snapshot into a new editable Design project without exposing the source payload.",
|
|
33
|
+
schema: z.object({
|
|
34
|
+
contextId: z.string(),
|
|
35
|
+
artifactKey: z.string(),
|
|
36
|
+
resourceId: z.string(),
|
|
37
|
+
expectedUpdatedAt: z.string().optional(),
|
|
38
|
+
title: z.string().optional(),
|
|
39
|
+
}),
|
|
40
|
+
publicAgent: { expose: true, readOnly: false, requiresAuth: true },
|
|
41
|
+
run: async (args) => {
|
|
42
|
+
const reference = await resolveNativeContextCloneReference({
|
|
43
|
+
appId: "design",
|
|
44
|
+
resourceType: "design",
|
|
45
|
+
resourceId: args.resourceId,
|
|
46
|
+
expectedUpdatedAt: args.expectedUpdatedAt,
|
|
47
|
+
contextId: args.contextId,
|
|
48
|
+
artifactKey: args.artifactKey,
|
|
49
|
+
});
|
|
50
|
+
const raw = await readPrivateBlob(
|
|
51
|
+
reference.cloneHandle as PrivateBlobHandle,
|
|
52
|
+
);
|
|
53
|
+
const body = Buffer.from(raw.data).toString("utf8");
|
|
54
|
+
const hash = createHash("sha256").update(body).digest("hex");
|
|
55
|
+
if (
|
|
56
|
+
raw.metadata?.appId !== "design" ||
|
|
57
|
+
raw.metadata?.resourceType !== "design" ||
|
|
58
|
+
raw.metadata?.resourceId !== args.resourceId ||
|
|
59
|
+
raw.metadata?.contentHash !== hash
|
|
60
|
+
)
|
|
61
|
+
throw new Error(
|
|
62
|
+
"Governed design clone payload failed integrity verification.",
|
|
63
|
+
);
|
|
64
|
+
const payload = payloadSchema.parse(JSON.parse(body));
|
|
65
|
+
const created = await createDesign.run({
|
|
66
|
+
title: args.title?.trim() || "Context design",
|
|
67
|
+
projectType: "prototype",
|
|
68
|
+
});
|
|
69
|
+
const saved = await saveImportedDesignFiles({
|
|
70
|
+
designId: created.id,
|
|
71
|
+
sourceType: "creative-context-native-clone",
|
|
72
|
+
preserveExactContent: true,
|
|
73
|
+
files: payload.files.map((file) => ({
|
|
74
|
+
...file,
|
|
75
|
+
source: {
|
|
76
|
+
creativeContextItemVersionId: reference.publishedItemVersionId,
|
|
77
|
+
},
|
|
78
|
+
})),
|
|
79
|
+
});
|
|
80
|
+
if (saved.files.length !== payload.files.length)
|
|
81
|
+
throw new Error("Design clone did not persist every saved file.");
|
|
82
|
+
const capturedData = z
|
|
83
|
+
.record(z.string(), z.unknown())
|
|
84
|
+
.parse(JSON.parse(payload.designData));
|
|
85
|
+
const {
|
|
86
|
+
canvasFrames: _capturedFrames,
|
|
87
|
+
screenMetadata: _capturedMetadata,
|
|
88
|
+
...capturedState
|
|
89
|
+
} = capturedData;
|
|
90
|
+
await mutateDesignData({
|
|
91
|
+
designId: created.id,
|
|
92
|
+
mutate: (current) => ({
|
|
93
|
+
...capturedState,
|
|
94
|
+
canvasFrames: current.canvasFrames,
|
|
95
|
+
screenMetadata: current.screenMetadata,
|
|
96
|
+
}),
|
|
97
|
+
isApplied: (persisted) =>
|
|
98
|
+
Object.entries(capturedState).every(
|
|
99
|
+
([key, value]) =>
|
|
100
|
+
JSON.stringify(persisted[key]) === JSON.stringify(value),
|
|
101
|
+
),
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
designId: saved.designId,
|
|
105
|
+
title: created.title,
|
|
106
|
+
fileCount: saved.files.length,
|
|
107
|
+
urlPath: saved.urlPath,
|
|
108
|
+
clonedExactVersion: reference.publishedItemVersionId,
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
});
|