@agent-native/core 0.141.5 → 0.141.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +20 -8
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
- package/corpus/templates/analytics/AGENTS.md +2 -2
- package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/get-first-party-analytics-health.ts +15 -1
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
- package/corpus/templates/analytics/actions/navigate.ts +1 -1
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -2
- package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
- package/corpus/templates/analytics/actions/view-screen.ts +0 -20
- package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
- package/corpus/templates/analytics/app/i18n-data.ts +330 -90
- package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +66 -30
- package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
- package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
- package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/analytics/app/routes/team.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-now-repair-automatically-after-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
- package/corpus/templates/analytics/netlify.toml +4 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +109 -0
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
- package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +342 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
- package/corpus/templates/analytics/server/lib/analytics-rollup-lock.ts +8 -0
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +11 -29
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +55 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1058 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +151 -46
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +15 -9
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +59 -17
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -4
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +61 -0
- package/corpus/templates/analytics/server/plugins/db.ts +58 -187
- package/corpus/templates/analytics/server/routes/api/analytics-rollups/backfill.post.ts +53 -0
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +8 -6
- package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
- package/corpus/templates/assets/AGENTS.md +1 -0
- package/corpus/templates/assets/actions/_helpers.ts +12 -0
- package/corpus/templates/assets/actions/generate-image.ts +9 -3
- package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/assets/app/routes/settings.tsx +5 -0
- package/corpus/templates/assets/app/routes/team.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
- package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +58 -0
- package/corpus/templates/assets/shared/api.ts +12 -0
- package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/brain/app/routes/team.tsx +1 -1
- package/corpus/templates/brain/app/routes.ts +1 -1
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/chat/app/root.tsx +1 -1
- package/corpus/templates/chat/app/routes/agent.tsx +7 -7
- package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/chat/app/routes/team.tsx +1 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/clips/changelog/2026-08-05-clips-overlays-now-use-clean-surfaces-without-clipped-shadow.md +6 -0
- package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -2
- package/corpus/templates/clips/desktop/src/styles.css +3 -54
- package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -3
- package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/content/e2e/global-setup.ts +1 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
- package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/design/actions/get-design-system.ts +3 -1
- package/corpus/templates/design/actions/import-from-url.ts +6 -5
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
- package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/design/app/routes/team.tsx +1 -1
- package/corpus/templates/design/changelog/2026-08-05-missing-design-systems-now-return-a-clear-not-found-response.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +1 -1
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/factory/app/routes/team.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/forms/shared/navigation.ts +1 -1
- package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/macros/app/routes/team.tsx +1 -1
- package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/plan/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +3 -1
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/slides/actions/import-from-url.ts +6 -6
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -2
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +3 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +9 -3
- package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
- package/corpus/templates/slides/app/global.css +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +5 -5
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +9 -5
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
- package/corpus/templates/slides/app/pages/Index.tsx +16 -5
- package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/slides/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-new-presentation-prompts-now-clearly-describe-presentation-g.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
- package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
- package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +49 -3
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.js +8 -0
- package/dist/agent/types.d.ts +7 -0
- package/dist/client/AssistantChat.js +1 -1
- package/dist/client/agent-chat-adapter.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +30 -3
- package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
- package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
- package/dist/client/chat/run-recovery.d.ts +2 -1
- package/dist/client/chat/run-recovery.js +14 -3
- package/dist/client/embed-auth.js +6 -2
- package/dist/client/error-format.d.ts +1 -0
- package/dist/client/error-format.js +16 -2
- package/dist/client/integrations/IntegrationsPanel.js +40 -6
- package/dist/client/org/OrgSwitcher.js +2 -2
- package/dist/client/org/TeamPage.js +92 -72
- package/dist/client/require-session.d.ts +1 -1
- package/dist/client/require-session.js +3 -3
- package/dist/client/resources/use-mcp-servers.d.ts +5 -0
- package/dist/client/resources/use-mcp-servers.js +36 -0
- package/dist/client/settings/AccountSettingsCard.js +40 -35
- package/dist/client/settings/AutomationsSection.js +1 -1
- package/dist/client/settings/DemoModeSection.d.ts +3 -1
- package/dist/client/settings/DemoModeSection.js +4 -1
- package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
- package/dist/client/settings/SchedulingTimezoneField.js +9 -5
- package/dist/client/settings/SettingsPanel.d.ts +4 -1
- package/dist/client/settings/SettingsPanel.js +21 -21
- package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
- package/dist/client/settings/SettingsTabsPage.js +98 -45
- package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
- package/dist/client/settings/useSettingsPanelController.js +47 -8
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/ingestion/website.d.ts +30 -0
- package/dist/localization/default-messages.d.ts +5 -0
- package/dist/localization/default-messages.js +5 -0
- package/dist/mcp-client/oauth-routes.js +1 -1
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.js +49 -0
- package/dist/navigation/index.js +16 -5
- package/dist/observability/routes.d.ts +3 -3
- package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/scripts/call-agent.js +11 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +9 -7
- package/dist/server/identity-sso.js +2 -1
- package/dist/server/onboarding-html.js +57 -34
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.js +1 -1
- package/dist/setup-connections/onboarding.js +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/sign-in-journey.d.ts +5 -2
- package/dist/shared/sign-in-journey.js +10 -4
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/dist/templates/chat/app/root.tsx +1 -1
- package/dist/templates/chat/app/routes/agent.tsx +7 -7
- package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
- package/dist/templates/chat/app/routes/team.tsx +1 -1
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/docs/content/authentication.mdx +4 -5
- package/docs/content/template-analytics-developers.mdx +1 -1
- package/docs/content/template-calendar-developers.mdx +1 -1
- package/docs/content/template-chat-developers.mdx +2 -2
- package/docs/content/template-content-developers.mdx +1 -1
- package/docs/content/template-mail-developers.mdx +1 -1
- package/docs/content/template-plan-developers.mdx +1 -1
- package/docs/content/toolkit-command-navigation.mdx +6 -6
- package/docs/content/toolkit-org-team.mdx +1 -1
- package/docs/content/toolkit-settings.mdx +8 -8
- package/docs/content/toolkit-setup-connections.mdx +1 -1
- package/package.json +1 -1
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/src/templates/chat/app/root.tsx +1 -1
- package/src/templates/chat/app/routes/agent.tsx +7 -7
- package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/src/templates/chat/app/routes/settings.$.tsx +1 -0
- package/src/templates/chat/app/routes/team.tsx +1 -1
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
- package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
- package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
- package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-stay-complete-and-atomic.md +0 -6
- package/corpus/templates/analytics/changelog/2026-08-05-historical-rollups-stay-complete-while-live-events-arrive.md +0 -6
- package/src/templates/default/actions/navigate.spec.ts +0 -53
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -176,7 +176,7 @@ export default async function globalSetup(config: FullConfig) {
|
|
|
176
176
|
const page = await context.newPage();
|
|
177
177
|
|
|
178
178
|
try {
|
|
179
|
-
await page.goto(`${baseURL}/
|
|
179
|
+
await page.goto(`${baseURL}/sign-in`, {
|
|
180
180
|
waitUntil: "domcontentloaded",
|
|
181
181
|
});
|
|
182
182
|
|
|
@@ -231,7 +231,7 @@ function resolvePath(
|
|
|
231
231
|
case "threads":
|
|
232
232
|
return "/thread-debug";
|
|
233
233
|
case "team":
|
|
234
|
-
return "/settings
|
|
234
|
+
return "/settings/organization";
|
|
235
235
|
case "extensions":
|
|
236
236
|
return command?.extensionId
|
|
237
237
|
? `/extensions/${encodeURIComponent(command.extensionId)}`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./_app.settings.js";
|
|
@@ -73,7 +73,7 @@ export function formsRoutePath(target: FormsNavigationTarget): string | null {
|
|
|
73
73
|
? `/response-insights?formId=${encodeURIComponent(formId)}`
|
|
74
74
|
: "/response-insights";
|
|
75
75
|
case "team":
|
|
76
|
-
return "/settings
|
|
76
|
+
return "/settings/organization";
|
|
77
77
|
case "extensions":
|
|
78
78
|
return "/extensions";
|
|
79
79
|
case "form-preview":
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, meta } from "./settings.js";
|
|
@@ -19,7 +19,9 @@ Design systems are stored in the `design_systems` SQL table. Each has a `data` c
|
|
|
19
19
|
## Creating a Design System
|
|
20
20
|
|
|
21
21
|
1. User provides brand context (company name, website, assets, notes)
|
|
22
|
-
2. `analyze-brand-assets`
|
|
22
|
+
2. `analyze-brand-assets` renders a website in a real browser and gathers the
|
|
23
|
+
computed visual system (colors, fonts, spacing, radii, shadows, components,
|
|
24
|
+
CSS variables, logos, and design.md-style guidance)
|
|
23
25
|
3. Agent analyzes the data and calls `create-design-system` with extracted tokens
|
|
24
26
|
4. The design system is published and becomes available for deck creation
|
|
25
27
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
3
|
-
normalizeBrandWebsiteUrl,
|
|
4
|
-
fetchBrandWebsiteSignals,
|
|
5
|
-
} from "@agent-native/core/brand-kit";
|
|
2
|
+
import { normalizeBrandWebsiteUrl } from "@agent-native/core/brand-kit";
|
|
6
3
|
import { resolveAccess } from "@agent-native/core/sharing";
|
|
4
|
+
import { extractRenderedDesignSystemFromUrl } from "@agent-native/creative-context/server";
|
|
7
5
|
import { z } from "zod";
|
|
8
6
|
|
|
9
7
|
import "../server/db/index.js"; // ensure registerShareableResource runs
|
|
@@ -14,8 +12,9 @@ export { normalizeBrandWebsiteUrl };
|
|
|
14
12
|
export default defineAction({
|
|
15
13
|
description:
|
|
16
14
|
"Gather brand data from various sources for agent analysis. " +
|
|
17
|
-
"If a websiteUrl is provided,
|
|
18
|
-
"
|
|
15
|
+
"If a websiteUrl is provided, renders the page in a real browser and extracts " +
|
|
16
|
+
"computed colors, typography, spacing, radii, shadows, component styles, " +
|
|
17
|
+
"CSS custom properties, logo references, and a design.md-style summary. " +
|
|
19
18
|
"If a designSystemId is provided, includes its existing data. " +
|
|
20
19
|
"Returns structured data the agent can use to build or refine a design system.",
|
|
21
20
|
schema: z.object({
|
|
@@ -61,7 +60,8 @@ export default defineAction({
|
|
|
61
60
|
|
|
62
61
|
// Fetch and analyze website if URL provided
|
|
63
62
|
if (websiteUrl) {
|
|
64
|
-
result.websiteAnalysis =
|
|
63
|
+
result.websiteAnalysis =
|
|
64
|
+
await extractRenderedDesignSystemFromUrl(websiteUrl);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
return result;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import { extractRenderedDesignSystemFromUrl } from "@agent-native/creative-context/server";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
export default defineAction({
|
|
6
6
|
description:
|
|
7
|
-
"Analyze a website URL
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
7
|
+
"Analyze a website URL in a real browser and return a bounded design.md-style " +
|
|
8
|
+
"visual system: computed colors, typography, spacing, radii, shadows, " +
|
|
9
|
+
"component styles, CSS variables, logo references, and reusable Brand Kit data. " +
|
|
10
|
+
"Uses a static SSRF-safe fallback only when a browser is unavailable.",
|
|
11
11
|
schema: z.object({
|
|
12
12
|
url: z.string().describe("Website URL to analyze"),
|
|
13
13
|
}),
|
|
14
14
|
readOnly: true,
|
|
15
15
|
http: { method: "GET" },
|
|
16
16
|
run: async ({ url }) => {
|
|
17
|
-
return
|
|
17
|
+
return extractRenderedDesignSystemFromUrl(url);
|
|
18
18
|
},
|
|
19
19
|
});
|
|
@@ -190,7 +190,7 @@ export default function DeckCard({
|
|
|
190
190
|
{deck.starred ? (
|
|
191
191
|
<IconStarFilled className="h-3.5 w-3.5 text-[#F5C451]" />
|
|
192
192
|
) : (
|
|
193
|
-
<IconStar className="h-3.5 w-3.5 text-
|
|
193
|
+
<IconStar className="h-3.5 w-3.5 text-white/70" />
|
|
194
194
|
)}
|
|
195
195
|
</button>
|
|
196
196
|
)}
|
|
@@ -208,7 +208,7 @@ export default function DeckCard({
|
|
|
208
208
|
}`}
|
|
209
209
|
aria-label={t("raw.deckOptions")}
|
|
210
210
|
>
|
|
211
|
-
<IconDots className="w-3.5 h-3.5 text-
|
|
211
|
+
<IconDots className="w-3.5 h-3.5 text-white/70" />
|
|
212
212
|
</button>
|
|
213
213
|
</DropdownMenuTrigger>
|
|
214
214
|
<DropdownMenuContent
|
|
@@ -479,7 +479,7 @@ export function DesignSystemSetup({
|
|
|
479
479
|
|
|
480
480
|
if (websiteUrls.length > 0) {
|
|
481
481
|
parts.push(
|
|
482
|
-
`\n## Website URLs\nAnalyze these websites for design tokens. Call \`import-from-url\` for each:\n${websiteUrls.map((u) => `- ${u}`).join("\n")}
|
|
482
|
+
`\n## Website URLs\nAnalyze these websites for design tokens. Call \`import-from-url\` for each:\n${websiteUrls.map((u) => `- ${u}`).join("\n")}\n\nThe shared action uses the layered real-browser renderer so hydrated React, CSS-in-JS, Tailwind, SPA content, loaded fonts, computed colors, component styles, CSS variables, and desktop/mobile screenshot evidence are captured consistently. It falls back explicitly to SSRF-safe static extraction only when a browser is unavailable. Use its design.md-style result as the source of truth for the deck style.`,
|
|
483
483
|
);
|
|
484
484
|
}
|
|
485
485
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { appBasePath } from "@agent-native/core/client/api-path";
|
|
2
2
|
import { PromptComposer } from "@agent-native/core/client/composer";
|
|
3
|
+
import { ensureEmbedAuthFetchInterceptor } from "@agent-native/core/client/host";
|
|
3
4
|
import { useT } from "@agent-native/core/client/i18n";
|
|
4
5
|
import { useState, useEffect, useCallback, useRef } from "react";
|
|
5
6
|
import { createPortal } from "react-dom";
|
|
@@ -22,9 +23,11 @@ export async function uploadPromptFiles(
|
|
|
22
23
|
if (files.length === 0) return [];
|
|
23
24
|
const formData = new FormData();
|
|
24
25
|
files.forEach((file) => formData.append("files", file));
|
|
26
|
+
ensureEmbedAuthFetchInterceptor();
|
|
25
27
|
const response = await fetch(`${appBasePath()}/api/uploads`, {
|
|
26
28
|
method: "POST",
|
|
27
29
|
body: formData,
|
|
30
|
+
credentials: "include",
|
|
28
31
|
});
|
|
29
32
|
if (!response.ok) {
|
|
30
33
|
let message = "Upload failed";
|
|
@@ -4112,7 +4112,7 @@ export default function SlideEditor({
|
|
|
4112
4112
|
// to stay mounted or that background becomes uneditable.
|
|
4113
4113
|
const contextToolbar = !readOnly ? (
|
|
4114
4114
|
<div
|
|
4115
|
-
className="
|
|
4115
|
+
className="shrink-0"
|
|
4116
4116
|
// Snapshotting the range is only half the job: without this marker the
|
|
4117
4117
|
// click-outside handler exits the edit and clears the snapshot before
|
|
4118
4118
|
// the button's onClick runs, so partial-text formatting would silently
|
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
uploadPromptFiles,
|
|
16
16
|
type UploadedFile,
|
|
17
17
|
} from "@/components/editor/PromptDialog";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
describeDeckPersistenceFailure,
|
|
20
|
+
useDecks,
|
|
21
|
+
} from "@/context/DeckContext";
|
|
19
22
|
import { useAgentGenerating } from "@/hooks/use-agent-generating";
|
|
20
23
|
import { useDesignSystems } from "@/hooks/use-design-systems";
|
|
21
24
|
import { useWorkspaceDefaults } from "@/hooks/use-workspace-defaults";
|
|
@@ -141,12 +144,15 @@ export function FirstDeckOnboardingFlow({
|
|
|
141
144
|
onUnauthenticated: () => {
|
|
142
145
|
toast.error(t("home.signInTitle"));
|
|
143
146
|
},
|
|
144
|
-
onPersistenceFailure: (failedPrompt) => {
|
|
147
|
+
onPersistenceFailure: (failedPrompt, _failedFiles, failure) => {
|
|
145
148
|
setPromptInitialText(failedPrompt);
|
|
146
149
|
setPromptInitialTextKey(Date.now());
|
|
147
150
|
setStep("prompt");
|
|
148
151
|
toast.error(t("home.generationStartFailed"), {
|
|
149
|
-
description:
|
|
152
|
+
description: describeDeckPersistenceFailure(
|
|
153
|
+
failure,
|
|
154
|
+
t("home.generationStartFailedDescription"),
|
|
155
|
+
),
|
|
150
156
|
});
|
|
151
157
|
},
|
|
152
158
|
});
|
|
@@ -138,6 +138,25 @@ export interface Deck {
|
|
|
138
138
|
aspectRatio?: AspectRatio;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
export type DeckPersistenceResult =
|
|
142
|
+
| { persisted: true }
|
|
143
|
+
| { persisted: false; reason: "request-failed"; error: unknown }
|
|
144
|
+
| { persisted: false; reason: "not-found" };
|
|
145
|
+
|
|
146
|
+
export function describeDeckPersistenceFailure(
|
|
147
|
+
result: DeckPersistenceResult,
|
|
148
|
+
fallback: string,
|
|
149
|
+
): string {
|
|
150
|
+
if (result.persisted || result.reason === "not-found") return fallback;
|
|
151
|
+
if (result.error instanceof Error && result.error.message.trim()) {
|
|
152
|
+
return result.error.message;
|
|
153
|
+
}
|
|
154
|
+
if (typeof result.error === "string" && result.error.trim()) {
|
|
155
|
+
return result.error;
|
|
156
|
+
}
|
|
157
|
+
return fallback;
|
|
158
|
+
}
|
|
159
|
+
|
|
141
160
|
interface DeckContextType {
|
|
142
161
|
decks: Deck[];
|
|
143
162
|
loading: boolean;
|
|
@@ -146,7 +165,7 @@ interface DeckContextType {
|
|
|
146
165
|
title?: string,
|
|
147
166
|
options?: { noDefaultSlides?: boolean; designSystemId?: string | null },
|
|
148
167
|
) => Deck;
|
|
149
|
-
ensureDeckPersisted: (id: string) => Promise<
|
|
168
|
+
ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
|
|
150
169
|
/**
|
|
151
170
|
* Optimistically duplicate a deck. Inserts a copy into local state with the
|
|
152
171
|
* supplied `newId` immediately so the UI can navigate without awaiting the
|
|
@@ -167,6 +186,7 @@ interface DeckContextType {
|
|
|
167
186
|
) => void;
|
|
168
187
|
reloadDecks: () => Promise<void>;
|
|
169
188
|
reloadDecksWithStatus: () => Promise<DeckReloadStatus>;
|
|
189
|
+
refreshOpenDeck: (deckId: string) => Promise<Deck | null>;
|
|
170
190
|
getDeck: (id: string) => Deck | undefined;
|
|
171
191
|
addSlide: (
|
|
172
192
|
deckId: string,
|
|
@@ -885,7 +905,22 @@ async function fetchDecksForCurrentRoute(): Promise<Deck[] | null> {
|
|
|
885
905
|
}
|
|
886
906
|
|
|
887
907
|
async function deleteDeckFromAPI(id: string): Promise<void> {
|
|
888
|
-
|
|
908
|
+
try {
|
|
909
|
+
await callAction("delete-deck", { id }, { method: "DELETE" });
|
|
910
|
+
} catch (error) {
|
|
911
|
+
// Deleting an optimistic deck is intentionally idempotent. A create can
|
|
912
|
+
// fail after the server committed the row, or before it created one.
|
|
913
|
+
if (
|
|
914
|
+
!(
|
|
915
|
+
error &&
|
|
916
|
+
typeof error === "object" &&
|
|
917
|
+
"status" in error &&
|
|
918
|
+
(error as { status?: unknown }).status === 404
|
|
919
|
+
)
|
|
920
|
+
) {
|
|
921
|
+
throw error;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
889
924
|
}
|
|
890
925
|
|
|
891
926
|
async function createDeckOnAPI(deck: Deck): Promise<void> {
|
|
@@ -1081,7 +1116,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1081
1116
|
const deletion = pendingCreate
|
|
1082
1117
|
? pendingCreate.then(
|
|
1083
1118
|
() => deleteDeckFromAPI(deckId),
|
|
1084
|
-
() =>
|
|
1119
|
+
() => deleteDeckFromAPI(deckId),
|
|
1085
1120
|
)
|
|
1086
1121
|
: deleteDeckFromAPI(deckId);
|
|
1087
1122
|
void deletion.catch((err) => {
|
|
@@ -1267,11 +1302,11 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1267
1302
|
// - Dirty deck / unsaved local create → additive merge only: surface
|
|
1268
1303
|
// agent-added slides without ever overwriting or dropping local slides.
|
|
1269
1304
|
const refetchOpenDeckIfChanged = useCallback(
|
|
1270
|
-
async (currentOpenId: string) => {
|
|
1305
|
+
async (currentOpenId: string): Promise<Deck | null> => {
|
|
1271
1306
|
const serverDeck = await fetchDeckFromAPI(currentOpenId);
|
|
1272
1307
|
// Null means 404 (row not created yet), a transient failure, or a
|
|
1273
1308
|
// still-pending create — nothing authoritative to reconcile.
|
|
1274
|
-
if (!serverDeck) return;
|
|
1309
|
+
if (!serverDeck) return null;
|
|
1275
1310
|
const clientDeck = decksRef.current.find((d) => d.id === currentOpenId);
|
|
1276
1311
|
|
|
1277
1312
|
const hasLocalEdits =
|
|
@@ -1281,7 +1316,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1281
1316
|
if (hasLocalEdits && clientDeck) {
|
|
1282
1317
|
// Content-preserving: only ADD server slides missing locally.
|
|
1283
1318
|
const merged = mergeServerAddedSlides(clientDeck, serverDeck);
|
|
1284
|
-
if (merged === clientDeck) return; // nothing new to surface
|
|
1319
|
+
if (merged === clientDeck) return serverDeck; // nothing new to surface
|
|
1285
1320
|
lastExternalUpdateRef.current = Date.now();
|
|
1286
1321
|
setDecks((prev) => {
|
|
1287
1322
|
const idx = prev.findIndex((d) => d.id === currentOpenId);
|
|
@@ -1290,16 +1325,17 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1290
1325
|
next[idx] = merged;
|
|
1291
1326
|
return next;
|
|
1292
1327
|
});
|
|
1293
|
-
return;
|
|
1328
|
+
return serverDeck;
|
|
1294
1329
|
}
|
|
1295
1330
|
|
|
1296
1331
|
const changed =
|
|
1297
1332
|
!clientDeck ||
|
|
1298
1333
|
clientDeck.updatedAt !== serverDeck.updatedAt ||
|
|
1299
|
-
clientDeck
|
|
1300
|
-
if (!changed) return;
|
|
1334
|
+
deckContentSignature(clientDeck) !== deckContentSignature(serverDeck);
|
|
1335
|
+
if (!changed) return serverDeck;
|
|
1301
1336
|
lastExternalUpdateRef.current = Date.now();
|
|
1302
1337
|
applyRemoteDeckUpdate(serverDeck);
|
|
1338
|
+
return serverDeck;
|
|
1303
1339
|
},
|
|
1304
1340
|
[applyRemoteDeckUpdate],
|
|
1305
1341
|
);
|
|
@@ -1728,19 +1764,33 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1728
1764
|
[noteLocalCreate, setDecksLocal],
|
|
1729
1765
|
);
|
|
1730
1766
|
|
|
1731
|
-
const ensureDeckPersisted = useCallback(
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1767
|
+
const ensureDeckPersisted = useCallback(
|
|
1768
|
+
async (id: string): Promise<DeckPersistenceResult> => {
|
|
1769
|
+
const pendingCreate = pendingCreatePromisesRef.current.get(id);
|
|
1770
|
+
if (pendingCreate) {
|
|
1771
|
+
try {
|
|
1772
|
+
await pendingCreate;
|
|
1773
|
+
return { persisted: true };
|
|
1774
|
+
} catch (error) {
|
|
1775
|
+
return { persisted: false, reason: "request-failed", error };
|
|
1776
|
+
}
|
|
1739
1777
|
}
|
|
1740
|
-
}
|
|
1741
1778
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1779
|
+
try {
|
|
1780
|
+
const result = await callAction<unknown>(
|
|
1781
|
+
"get-deck",
|
|
1782
|
+
{ id },
|
|
1783
|
+
{ method: "GET" },
|
|
1784
|
+
);
|
|
1785
|
+
return normalizeActionDeck(result)
|
|
1786
|
+
? { persisted: true }
|
|
1787
|
+
: { persisted: false, reason: "not-found" };
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
return { persisted: false, reason: "request-failed", error };
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
[],
|
|
1793
|
+
);
|
|
1744
1794
|
|
|
1745
1795
|
const duplicateDeck = useCallback(
|
|
1746
1796
|
(sourceDeckId: string, newId: string, title?: string): Deck | null => {
|
|
@@ -2150,6 +2200,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
2150
2200
|
updateDeck,
|
|
2151
2201
|
reloadDecks,
|
|
2152
2202
|
reloadDecksWithStatus,
|
|
2203
|
+
refreshOpenDeck: refetchOpenDeckIfChanged,
|
|
2153
2204
|
getDeck,
|
|
2154
2205
|
addSlide,
|
|
2155
2206
|
updateSlide,
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
@source "./**/*.{ts,tsx}";
|
|
16
16
|
|
|
17
|
+
/* Keep the editable agent prompt readable even if the generated text utility
|
|
18
|
+
is missing or loses a cascade tie during the hosted build. */
|
|
19
|
+
.agent-composer-root [data-agent-composer-slot="editor-input"] {
|
|
20
|
+
color: hsl(var(--foreground));
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
/* Hide the sidebar's built-in collapsed tab strip — AgentToggleButton in the
|
|
18
24
|
toolbar serves this purpose instead, so we don't want a redundant bar. */
|
|
19
25
|
button[title="Open agent sidebar"] {
|
|
@@ -654,17 +654,17 @@ const messages = {
|
|
|
654
654
|
mine: "Mine",
|
|
655
655
|
deckCount_one: "deck",
|
|
656
656
|
deckCount_other: "decks",
|
|
657
|
-
createDeckOrVisual: "Create a
|
|
657
|
+
createDeckOrVisual: "Create a presentation",
|
|
658
658
|
noMineDecks: "No decks created by you yet.",
|
|
659
659
|
deleteDeckTitle: "Delete Deck?",
|
|
660
660
|
deleteDeckDescription:
|
|
661
661
|
"This will permanently delete this deck and all its slides. This action cannot be undone.",
|
|
662
662
|
cancel: "Cancel",
|
|
663
663
|
delete: "Delete",
|
|
664
|
-
newDeckPromptTitle: "New
|
|
665
|
-
newDeckPlaceholder: "Describe
|
|
664
|
+
newDeckPromptTitle: "New presentation",
|
|
665
|
+
newDeckPlaceholder: "Describe the presentation you want to generate...",
|
|
666
666
|
skipPrompt: "Skip prompt",
|
|
667
|
-
firstDeckPromptTitle: "What
|
|
667
|
+
firstDeckPromptTitle: "What kind of presentation should we generate?",
|
|
668
668
|
firstDeckSkip: "Skip",
|
|
669
669
|
chooseReferences: "Choose references",
|
|
670
670
|
addDesignSystem: "+ Design system",
|
|
@@ -716,7 +716,7 @@ const messages = {
|
|
|
716
716
|
emptyTitle: "No decks yet",
|
|
717
717
|
createFirstDeck: "Create your first deck",
|
|
718
718
|
emptyDescription:
|
|
719
|
-
"Build beautiful presentations
|
|
719
|
+
"Build beautiful presentations with AI-powered generation.",
|
|
720
720
|
},
|
|
721
721
|
};
|
|
722
722
|
|
|
@@ -4,7 +4,7 @@ import { flushSync } from "react-dom";
|
|
|
4
4
|
|
|
5
5
|
import type { NewDeckReferenceSelection } from "@/components/editor/NewDeckReferenceStep";
|
|
6
6
|
import type { UploadedFile } from "@/components/editor/PromptDialog";
|
|
7
|
-
import type { Deck } from "@/context/DeckContext";
|
|
7
|
+
import type { Deck, DeckPersistenceResult } from "@/context/DeckContext";
|
|
8
8
|
import { createDeckAgentMessage } from "@/lib/agent-visible-message";
|
|
9
9
|
|
|
10
10
|
interface DesignSystemGenerationContextResult {
|
|
@@ -150,13 +150,17 @@ export interface StartDeckGenerationOptions {
|
|
|
150
150
|
selectedReferenceDeckId?: string | null;
|
|
151
151
|
designSystems: Array<{ id: string; title: string }>;
|
|
152
152
|
createDeck: CreateDeck;
|
|
153
|
-
ensureDeckPersisted: (id: string) => Promise<
|
|
153
|
+
ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
|
|
154
154
|
deleteDeck: (id: string) => void;
|
|
155
155
|
navigate: Navigate;
|
|
156
156
|
agentSubmit: SubmitAgent;
|
|
157
157
|
onPromptClosed: () => void;
|
|
158
158
|
onUnauthenticated: (prompt: string, hadFiles: boolean) => void;
|
|
159
|
-
onPersistenceFailure: (
|
|
159
|
+
onPersistenceFailure: (
|
|
160
|
+
prompt: string,
|
|
161
|
+
files: UploadedFile[],
|
|
162
|
+
failure: DeckPersistenceResult,
|
|
163
|
+
) => void;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
/** Create the optimistic deck, hydrate references, and start the agent run. */
|
|
@@ -214,8 +218,8 @@ export async function startDeckGeneration({
|
|
|
214
218
|
onPromptClosed();
|
|
215
219
|
|
|
216
220
|
const persisted = await ensureDeckPersisted(deck.id);
|
|
217
|
-
if (!persisted) {
|
|
218
|
-
onPersistenceFailure(prompt, filesForGeneration);
|
|
221
|
+
if (!persisted.persisted) {
|
|
222
|
+
onPersistenceFailure(prompt, filesForGeneration, persisted);
|
|
219
223
|
deleteDeck(deckId);
|
|
220
224
|
return "failed";
|
|
221
225
|
}
|
|
@@ -155,6 +155,7 @@ export default function DeckEditor() {
|
|
|
155
155
|
getDeck,
|
|
156
156
|
reloadDecks,
|
|
157
157
|
reloadDecksWithStatus,
|
|
158
|
+
refreshOpenDeck,
|
|
158
159
|
updateDeck,
|
|
159
160
|
updateSlide,
|
|
160
161
|
deleteSlide,
|
|
@@ -396,6 +397,22 @@ export default function DeckEditor() {
|
|
|
396
397
|
}
|
|
397
398
|
}, [refetchOrg, reloadDecks]);
|
|
398
399
|
|
|
400
|
+
// The final generation write can race the last sync event. Pull the
|
|
401
|
+
// authoritative open deck when the run settles so a stale canvas does not
|
|
402
|
+
// require a browser refresh to reveal completed slides.
|
|
403
|
+
useEffect(() => {
|
|
404
|
+
if (
|
|
405
|
+
!id ||
|
|
406
|
+
!shouldClearNewDeckGeneratingState({
|
|
407
|
+
generating,
|
|
408
|
+
generationStarted: newDeckGenerationStarted.current,
|
|
409
|
+
})
|
|
410
|
+
) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
void refreshOpenDeck(id);
|
|
414
|
+
}, [generating, id, refreshOpenDeck]);
|
|
415
|
+
|
|
399
416
|
// Clean up the generating URL param/ref when generation completes or when
|
|
400
417
|
// the first slide lands, so partial progress is visible during long decks.
|
|
401
418
|
useEffect(() => {
|