@agent-native/core 0.101.12 → 0.101.14
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 +15 -0
- package/corpus/core/package.json +4 -2
- package/corpus/core/src/cli/create.ts +76 -17
- package/corpus/core/src/client/AgentPanel.tsx +61 -48
- package/corpus/core/src/client/assistant-ui-recovery.tsx +9 -3
- package/corpus/core/src/client/chat/message-components.tsx +26 -2
- package/corpus/core/src/client/chat/tool-call-display.tsx +18 -11
- package/corpus/core/src/mcp/server.ts +10 -1
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +0 -3
- package/corpus/core/src/server/agent-chat-plugin.ts +2 -58
- package/corpus/core/src/server/prompts/framework-core-compact.ts +0 -1
- package/corpus/core/src/server/prompts/framework-core.ts +0 -30
- package/corpus/core/src/server/prompts/index.ts +1 -4
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -14
- package/corpus/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +1 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/changelog/2026-07-15-public-clip-links-are-labeled-share-with-humans-for-clarity.md +6 -0
- package/corpus/templates/forms/actions/delete-form.ts +4 -0
- package/corpus/templates/forms/actions/patch-form-fields.ts +3 -0
- package/corpus/templates/forms/actions/restore-form.ts +3 -0
- package/corpus/templates/forms/actions/update-form.ts +3 -0
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +2 -2
- package/corpus/templates/forms/app/pages/ResponsesPage.tsx +2 -2
- package/corpus/templates/forms/changelog/2026-07-15-published-forms-now-reflect-field-updates-immediately-at-the.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-15-response-rows-now-keep-every-column-aligned-to-the-top-for-c.md +6 -0
- package/corpus/templates/forms/server/handlers/forms.ts +1 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +47 -4
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +189 -82
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -1
- package/dist/cli/create.d.ts +5 -2
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +52 -17
- package/dist/cli/create.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +2 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +24 -13
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/assistant-ui-recovery.d.ts +2 -0
- package/dist/client/assistant-ui-recovery.d.ts.map +1 -1
- package/dist/client/assistant-ui-recovery.js +5 -2
- package/dist/client/assistant-ui-recovery.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +6 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +15 -2
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +4 -2
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +11 -13
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +10 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +0 -3
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +0 -22
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +2 -51
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/prompts/framework-core-compact.d.ts +0 -1
- package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
- package/dist/server/prompts/framework-core-compact.js +0 -1
- package/dist/server/prompts/framework-core-compact.js.map +1 -1
- package/dist/server/prompts/framework-core.d.ts +0 -9
- package/dist/server/prompts/framework-core.d.ts.map +1 -1
- package/dist/server/prompts/framework-core.js +0 -29
- package/dist/server/prompts/framework-core.js.map +1 -1
- package/dist/server/prompts/index.d.ts +1 -1
- package/dist/server/prompts/index.d.ts.map +1 -1
- package/dist/server/prompts/index.js +1 -1
- package/dist/server/prompts/index.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/actions/SKILL.md +492 -0
- package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +189 -0
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +76 -0
- package/dist/templates/chat/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/dist/templates/chat/.agents/skills/create-skill/SKILL.md +221 -0
- package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/dist/templates/chat/.agents/skills/security/SKILL.md +280 -0
- package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +106 -0
- package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +95 -0
- package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/dist/templates/chat/.env.example +5 -0
- package/dist/templates/chat/.ignore +0 -0
- package/dist/templates/chat/.oxfmtrc.json +8 -0
- package/dist/templates/chat/.react-router/types/+server-build.d.ts +18 -0
- package/dist/templates/chat/.react-router/types/app/+types/root.ts +68 -0
- package/dist/templates/chat/AGENTS.md +62 -0
- package/dist/templates/chat/CHANGELOG.md +10 -0
- package/dist/templates/chat/DEVELOPING.md +185 -0
- package/dist/templates/chat/README.md +32 -0
- package/dist/templates/chat/_gitignore +43 -0
- package/dist/templates/chat/actions/hello.ts +13 -0
- package/dist/templates/chat/actions/navigate.ts +41 -0
- package/dist/templates/chat/actions/run.ts +2 -0
- package/dist/templates/chat/actions/view-screen.ts +31 -0
- package/dist/templates/chat/app/components/layout/Header.tsx +59 -0
- package/dist/templates/chat/app/components/layout/Layout.tsx +184 -0
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +580 -0
- package/dist/templates/chat/app/components/ui/button.tsx +1 -0
- package/dist/templates/chat/app/components/ui/card.tsx +1 -0
- package/dist/templates/chat/app/components/ui/dropdown-menu.tsx +1 -0
- package/dist/templates/chat/app/components/ui/input.tsx +1 -0
- package/dist/templates/chat/app/components/ui/label.tsx +1 -0
- package/dist/templates/chat/app/components/ui/sheet.tsx +1 -0
- package/dist/templates/chat/app/components/ui/toolkit-provider.tsx +12 -0
- package/dist/templates/chat/app/components/ui/tooltip.tsx +1 -0
- package/dist/templates/chat/app/entry.client.tsx +19 -0
- package/dist/templates/chat/app/entry.server.tsx +10 -0
- package/dist/templates/chat/app/global.css +93 -0
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +111 -0
- package/dist/templates/chat/app/i18n/ar-SA.ts +68 -0
- package/dist/templates/chat/app/i18n/de-DE.ts +71 -0
- package/dist/templates/chat/app/i18n/en-US.ts +70 -0
- package/dist/templates/chat/app/i18n/es-ES.ts +71 -0
- package/dist/templates/chat/app/i18n/fr-FR.ts +71 -0
- package/dist/templates/chat/app/i18n/hi-IN.ts +69 -0
- package/dist/templates/chat/app/i18n/index.ts +34 -0
- package/dist/templates/chat/app/i18n/ja-JP.ts +70 -0
- package/dist/templates/chat/app/i18n/ko-KR.ts +70 -0
- package/dist/templates/chat/app/i18n/pt-BR.ts +71 -0
- package/dist/templates/chat/app/i18n/zh-CN.ts +67 -0
- package/dist/templates/chat/app/i18n/zh-TW.ts +67 -0
- package/dist/templates/chat/app/i18n-data.ts +556 -0
- package/dist/templates/chat/app/lib/agent-page.tsx +40 -0
- package/dist/templates/chat/app/lib/app-config.ts +11 -0
- package/dist/templates/chat/app/lib/tab-id.ts +1 -0
- package/dist/templates/chat/app/lib/utils.ts +1 -0
- package/dist/templates/chat/app/root.tsx +172 -0
- package/dist/templates/chat/app/routes/_index.tsx +91 -0
- package/dist/templates/chat/app/routes/agent.tsx +17 -0
- package/dist/templates/chat/app/routes/chat.$threadId.tsx +1 -0
- package/dist/templates/chat/app/routes/database.tsx +17 -0
- package/dist/templates/chat/app/routes/extensions.$id.$slug.tsx +2 -0
- package/dist/templates/chat/app/routes/extensions.$id.tsx +11 -0
- package/dist/templates/chat/app/routes/extensions._index.tsx +11 -0
- package/dist/templates/chat/app/routes/extensions.tsx +5 -0
- package/dist/templates/chat/app/routes/observability.tsx +18 -0
- package/dist/templates/chat/app/routes/settings.tsx +88 -0
- package/dist/templates/chat/app/routes/team.tsx +11 -0
- package/dist/templates/chat/app/routes.ts +4 -0
- package/dist/templates/chat/app/vite-env.d.ts +6 -0
- package/dist/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/dist/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/dist/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/dist/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/dist/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/dist/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/dist/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/dist/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
- package/dist/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
- package/dist/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/dist/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/dist/templates/chat/components.json +20 -0
- package/dist/templates/chat/data/.gitkeep +0 -0
- package/dist/templates/chat/data/sync-config.json +1 -0
- package/dist/templates/chat/learnings.defaults.md +5 -0
- package/dist/templates/chat/netlify.toml +10 -0
- package/dist/templates/chat/package.json +92 -0
- package/dist/templates/chat/public/agent-native-icon-dark.svg +10 -0
- package/dist/templates/chat/public/agent-native-icon-light.svg +10 -0
- package/dist/templates/chat/public/agent-native-logo-dark.svg +21 -0
- package/dist/templates/chat/public/agent-native-logo-light.svg +21 -0
- package/dist/templates/chat/public/favicon.svg +1 -0
- package/dist/templates/chat/public/icon-180.svg +1 -0
- package/dist/templates/chat/public/icon-192.svg +1 -0
- package/dist/templates/chat/public/icon-512.svg +1 -0
- package/dist/templates/chat/public/manifest.json +21 -0
- package/dist/templates/chat/react-router.config.ts +7 -0
- package/dist/templates/chat/server/middleware/auth.ts +15 -0
- package/dist/templates/chat/server/plugins/agent-chat.ts +21 -0
- package/dist/templates/chat/server/plugins/auth.ts +17 -0
- package/dist/templates/chat/server/routes/[...page].get.ts +5 -0
- package/dist/templates/chat/ssr-entry.ts +15 -0
- package/dist/templates/chat/tsconfig.json +21 -0
- package/dist/templates/chat/vite.config.ts +19 -0
- package/package.json +2 -1
- package/src/templates/chat/.agents/skills/actions/SKILL.md +492 -0
- package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +189 -0
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +76 -0
- package/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +89 -0
- package/src/templates/chat/.agents/skills/create-skill/SKILL.md +221 -0
- package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +263 -0
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +232 -0
- package/src/templates/chat/.agents/skills/security/SKILL.md +280 -0
- package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +106 -0
- package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +95 -0
- package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
- package/src/templates/chat/.env.example +5 -0
- package/src/templates/chat/.ignore +0 -0
- package/src/templates/chat/.oxfmtrc.json +8 -0
- package/src/templates/chat/.react-router/types/+server-build.d.ts +18 -0
- package/src/templates/chat/.react-router/types/app/+types/root.ts +68 -0
- package/src/templates/chat/AGENTS.md +62 -0
- package/src/templates/chat/CHANGELOG.md +10 -0
- package/src/templates/chat/DEVELOPING.md +185 -0
- package/src/templates/chat/README.md +32 -0
- package/src/templates/chat/_gitignore +43 -0
- package/src/templates/chat/actions/hello.spec.ts +23 -0
- package/src/templates/chat/actions/hello.ts +13 -0
- package/src/templates/chat/actions/navigate.spec.ts +68 -0
- package/src/templates/chat/actions/navigate.ts +41 -0
- package/src/templates/chat/actions/run.ts +2 -0
- package/src/templates/chat/actions/view-screen.spec.ts +40 -0
- package/src/templates/chat/actions/view-screen.ts +31 -0
- package/src/templates/chat/app/components/layout/Header.tsx +59 -0
- package/src/templates/chat/app/components/layout/Layout.tsx +184 -0
- package/src/templates/chat/app/components/layout/Sidebar.tsx +580 -0
- package/src/templates/chat/app/components/ui/button.tsx +1 -0
- package/src/templates/chat/app/components/ui/card.tsx +1 -0
- package/src/templates/chat/app/components/ui/dropdown-menu.tsx +1 -0
- package/src/templates/chat/app/components/ui/input.tsx +1 -0
- package/src/templates/chat/app/components/ui/label.tsx +1 -0
- package/src/templates/chat/app/components/ui/sheet.tsx +1 -0
- package/src/templates/chat/app/components/ui/toolkit-provider.tsx +12 -0
- package/src/templates/chat/app/components/ui/tooltip.tsx +1 -0
- package/src/templates/chat/app/entry.client.tsx +19 -0
- package/src/templates/chat/app/entry.server.tsx +10 -0
- package/src/templates/chat/app/global.css +93 -0
- package/src/templates/chat/app/hooks/use-navigation-state.ts +111 -0
- package/src/templates/chat/app/i18n/ar-SA.ts +68 -0
- package/src/templates/chat/app/i18n/de-DE.ts +71 -0
- package/src/templates/chat/app/i18n/en-US.ts +70 -0
- package/src/templates/chat/app/i18n/es-ES.ts +71 -0
- package/src/templates/chat/app/i18n/fr-FR.ts +71 -0
- package/src/templates/chat/app/i18n/hi-IN.ts +69 -0
- package/src/templates/chat/app/i18n/index.ts +34 -0
- package/src/templates/chat/app/i18n/ja-JP.ts +70 -0
- package/src/templates/chat/app/i18n/ko-KR.ts +70 -0
- package/src/templates/chat/app/i18n/pt-BR.ts +71 -0
- package/src/templates/chat/app/i18n/zh-CN.ts +67 -0
- package/src/templates/chat/app/i18n/zh-TW.ts +67 -0
- package/src/templates/chat/app/i18n-data.ts +556 -0
- package/src/templates/chat/app/lib/agent-page.spec.tsx +52 -0
- package/src/templates/chat/app/lib/agent-page.tsx +40 -0
- package/src/templates/chat/app/lib/app-config.ts +11 -0
- package/src/templates/chat/app/lib/tab-id.ts +1 -0
- package/src/templates/chat/app/lib/utils.ts +1 -0
- package/src/templates/chat/app/root.tsx +172 -0
- package/src/templates/chat/app/routes/_index.tsx +91 -0
- package/src/templates/chat/app/routes/agent.tsx +17 -0
- package/src/templates/chat/app/routes/chat.$threadId.tsx +1 -0
- package/src/templates/chat/app/routes/database.tsx +17 -0
- package/src/templates/chat/app/routes/extensions.$id.$slug.tsx +2 -0
- package/src/templates/chat/app/routes/extensions.$id.tsx +11 -0
- package/src/templates/chat/app/routes/extensions._index.tsx +11 -0
- package/src/templates/chat/app/routes/extensions.tsx +5 -0
- package/src/templates/chat/app/routes/observability.tsx +18 -0
- package/src/templates/chat/app/routes/settings.tsx +88 -0
- package/src/templates/chat/app/routes/team.tsx +11 -0
- package/src/templates/chat/app/routes.ts +4 -0
- package/src/templates/chat/app/vite-env.d.ts +6 -0
- package/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
- package/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
- package/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
- package/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
- package/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
- package/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
- package/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
- package/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
- package/src/templates/chat/components.json +20 -0
- package/src/templates/chat/data/.gitkeep +0 -0
- package/src/templates/chat/data/sync-config.json +1 -0
- package/src/templates/chat/learnings.defaults.md +5 -0
- package/src/templates/chat/netlify.toml +10 -0
- package/src/templates/chat/package.json +92 -0
- package/src/templates/chat/public/agent-native-icon-dark.svg +10 -0
- package/src/templates/chat/public/agent-native-icon-light.svg +10 -0
- package/src/templates/chat/public/agent-native-logo-dark.svg +21 -0
- package/src/templates/chat/public/agent-native-logo-light.svg +21 -0
- package/src/templates/chat/public/favicon.svg +1 -0
- package/src/templates/chat/public/icon-180.svg +1 -0
- package/src/templates/chat/public/icon-192.svg +1 -0
- package/src/templates/chat/public/icon-512.svg +1 -0
- package/src/templates/chat/public/manifest.json +21 -0
- package/src/templates/chat/react-router.config.ts +7 -0
- package/src/templates/chat/server/middleware/auth.ts +15 -0
- package/src/templates/chat/server/plugins/agent-chat.ts +21 -0
- package/src/templates/chat/server/plugins/auth.ts +17 -0
- package/src/templates/chat/server/routes/[...page].get.ts +5 -0
- package/src/templates/chat/ssr-entry.ts +15 -0
- package/src/templates/chat/tsconfig.json +21 -0
- package/src/templates/chat/vite.config.ts +19 -0
|
@@ -86,7 +86,6 @@ import type {
|
|
|
86
86
|
MentionProvider,
|
|
87
87
|
} from "../agent/types.js";
|
|
88
88
|
import { readAppStateForCurrentTab } from "../application-state/script-helpers.js";
|
|
89
|
-
import { appStateGet } from "../application-state/store.js";
|
|
90
89
|
import {
|
|
91
90
|
createThread,
|
|
92
91
|
forkThread,
|
|
@@ -167,10 +166,7 @@ import {
|
|
|
167
166
|
} from "./framework-request-handler.js";
|
|
168
167
|
import { getOrigin } from "./google-oauth.js";
|
|
169
168
|
import { readBody } from "./h3-helpers.js";
|
|
170
|
-
import {
|
|
171
|
-
FIRST_SESSION_PERSONALIZATION,
|
|
172
|
-
getModelFamilyOverlay,
|
|
173
|
-
} from "./prompts/index.js";
|
|
169
|
+
import { getModelFamilyOverlay } from "./prompts/index.js";
|
|
174
170
|
import { mountRealtimeVoiceRoutes } from "./realtime-voice.js";
|
|
175
171
|
import {
|
|
176
172
|
runWithRequestContext,
|
|
@@ -283,41 +279,6 @@ export function buildLeanRunPolicyPrompt(
|
|
|
283
279
|
return codeEditingSurfaceRestriction + prodCodeExecPromptNote;
|
|
284
280
|
}
|
|
285
281
|
|
|
286
|
-
/**
|
|
287
|
-
* Returns whether `owner` has already finished (or explicitly skipped) the
|
|
288
|
-
* First-Session Personalization flow, via the owner-scoped
|
|
289
|
-
* `application_state` "personalization" flag the agent itself writes
|
|
290
|
-
* (`writeAppState("personalization", { done: true })` — see
|
|
291
|
-
* FIRST_SESSION_PERSONALIZATION in prompts/framework-core.ts).
|
|
292
|
-
*
|
|
293
|
-
* This used to be gated on "does this thread have prior messages", which
|
|
294
|
-
* flips false the instant a second request comes in for the SAME thread —
|
|
295
|
-
* making turn 2's system prompt diverge from turn 1's and invalidating the
|
|
296
|
-
* prompt-cache prefix on every thread's second request. The flow itself
|
|
297
|
-
* spans two turns (turn 1 asks the personalization questions and waits;
|
|
298
|
-
* turn 2 answers them and only then writes the "done" flag), so this flag
|
|
299
|
-
* is still false when BOTH turns' system prompts are assembled — turn 1
|
|
300
|
-
* and turn 2 come out byte-identical. It only flips once the flow
|
|
301
|
-
* completes, and it never flips back, so every later turn (and every
|
|
302
|
-
* later thread the same owner creates) stays consistent from then on. As
|
|
303
|
-
* a bonus, it also fixes a latent waste: the old gate re-included the
|
|
304
|
-
* ~1.5KB block on turn 1 of every new thread a user ever created, even
|
|
305
|
-
* long after they'd completed personalization once.
|
|
306
|
-
*/
|
|
307
|
-
export async function hasCompletedFirstSessionPersonalization(
|
|
308
|
-
owner: string,
|
|
309
|
-
): Promise<boolean> {
|
|
310
|
-
try {
|
|
311
|
-
const state = await appStateGet(owner, "personalization");
|
|
312
|
-
return state?.done === true;
|
|
313
|
-
} catch {
|
|
314
|
-
// Fail open to "not done" — same default as a brand-new user (block
|
|
315
|
-
// shown) rather than silently skipping personalization because of a
|
|
316
|
-
// transient appstate read error.
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
282
|
/**
|
|
322
283
|
* In-memory rate-limit tracker for `/generate-title`. Keyed by user email,
|
|
323
284
|
* value is recent invocation timestamps within the rolling window. Stale
|
|
@@ -2650,14 +2611,6 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2650
2611
|
)
|
|
2651
2612
|
? APP_RENDERED_CHAT_NO_DIRECT_CODE_PROMPT
|
|
2652
2613
|
: "";
|
|
2653
|
-
// Personalization block: included until this owner has finished (or
|
|
2654
|
-
// skipped) the flow — see hasCompletedFirstSessionPersonalization
|
|
2655
|
-
// for why this is gated on the owner-scoped appstate flag rather
|
|
2656
|
-
// than "is this a new thread" (keeps turn 1 and turn 2 identical).
|
|
2657
|
-
const personalizationBlock =
|
|
2658
|
-
(await hasCompletedFirstSessionPersonalization(owner))
|
|
2659
|
-
? ""
|
|
2660
|
-
: FIRST_SESSION_PERSONALIZATION;
|
|
2661
2614
|
// Per-model overlay: nudge GPT/Gemini engines toward our behavioral norms.
|
|
2662
2615
|
const modelOverlay = resolveModelOverlay();
|
|
2663
2616
|
// Stable-first ordering: base prompt / schema / extra come before
|
|
@@ -2712,13 +2665,10 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2712
2665
|
modelOverlay,
|
|
2713
2666
|
runtimeContext,
|
|
2714
2667
|
additionalFramework:
|
|
2715
|
-
|
|
2716
|
-
codeEditingSurfaceRestriction +
|
|
2717
|
-
prodCodeExecPromptNote,
|
|
2668
|
+
codeEditingSurfaceRestriction + prodCodeExecPromptNote,
|
|
2718
2669
|
});
|
|
2719
2670
|
return setSystemPromptOnContext(
|
|
2720
2671
|
basePrompt +
|
|
2721
|
-
personalizationBlock +
|
|
2722
2672
|
resources +
|
|
2723
2673
|
schemaBlock +
|
|
2724
2674
|
codeEditingSurfaceRestriction +
|
|
@@ -2940,10 +2890,6 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2940
2890
|
systemPrompt: async (event: any) => {
|
|
2941
2891
|
const { owner, extra } = await prepareRun(event);
|
|
2942
2892
|
const runtimeContext = runtimeContextForEvent(event);
|
|
2943
|
-
const personalizationBlock =
|
|
2944
|
-
(await hasCompletedFirstSessionPersonalization(owner))
|
|
2945
|
-
? ""
|
|
2946
|
-
: FIRST_SESSION_PERSONALIZATION;
|
|
2947
2893
|
const modelOverlay = resolveModelOverlay();
|
|
2948
2894
|
// Stable-first ordering: runtimeContext (day-granular) is
|
|
2949
2895
|
// appended LAST so a day rollover invalidates as little of the
|
|
@@ -2989,11 +2935,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
2989
2935
|
extra,
|
|
2990
2936
|
modelOverlay,
|
|
2991
2937
|
runtimeContext,
|
|
2992
|
-
additionalFramework: personalizationBlock,
|
|
2993
2938
|
});
|
|
2994
2939
|
return setSystemPromptOnContext(
|
|
2995
2940
|
devPrompt +
|
|
2996
|
-
personalizationBlock +
|
|
2997
2941
|
resources +
|
|
2998
2942
|
schemaBlock +
|
|
2999
2943
|
extra +
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* - Verbose "Extended Capabilities" section (agent uses get-framework-context)
|
|
8
8
|
* - Detailed "Parallel Tool Calls" prose (replaced with one-liner)
|
|
9
9
|
* - Detailed "Resources" section (agent uses resources tool)
|
|
10
|
-
* - "First-Session Personalization" (gated externally — see buildSystemPrompt)
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
12
|
import {
|
|
@@ -141,33 +141,3 @@ Each of these has a one-line pointer here and a full doc you can pull on demand
|
|
|
141
141
|
- **Structured memory** — persist knowledge across sessions with \`save-memory\` / \`delete-memory\`; save proactively when you learn preferences, corrections, or project context. Detailed instructions: call \`get-framework-context\` with key \`memory\`.
|
|
142
142
|
`;
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Build the First-Session Personalization block.
|
|
147
|
-
* Gated by caller: only include when the session has no prior messages
|
|
148
|
-
* (cheapest reliable signal that personalization hasn't run yet).
|
|
149
|
-
* Recording happens via writeAppState("personalization", { done: true })
|
|
150
|
-
* so the block is omitted from all subsequent requests once the agent
|
|
151
|
-
* completes the flow.
|
|
152
|
-
*/
|
|
153
|
-
export const FIRST_SESSION_PERSONALIZATION = `
|
|
154
|
-
### First-Session Personalization
|
|
155
|
-
|
|
156
|
-
On the user's very first interaction in this app, before answering their actual request, briefly personalize the workspace.
|
|
157
|
-
|
|
158
|
-
Check the application_state key \`personalization\` via \`readAppState("personalization")\`:
|
|
159
|
-
- If it returns null (or has no \`done: true\`), this is the first session — run the flow below.
|
|
160
|
-
- If \`done: true\` is set, skip the flow and answer normally.
|
|
161
|
-
|
|
162
|
-
**The flow (keep it to one short message, then wait for their answer before continuing):**
|
|
163
|
-
|
|
164
|
-
1. Greet briefly in one sentence.
|
|
165
|
-
2. Ask **two** yes/no questions inline, on separate lines:
|
|
166
|
-
- A theme question: _"Want me to pick a color theme for your workspace? I have a few presets — say a name or just 'yes' for my pick."_ Available presets: \`warm\`, \`ocean\`, \`forest\`, \`rose\`, \`slate\` (call \`change-appearance\` with one of these; or \`default\` to clear). When the user says yes without a name, pick one preset that fits this template's tone.
|
|
167
|
-
- A template-specific question that the template's AGENTS.md / CLAUDE.md documents (e.g. for calendar: _"Want me to color-code meetings by attendee or by category?"_; for mail: _"Want me to surface emails that look like they need a reply at the top?"_). If the template doesn't suggest a question, ask one generic preference question (e.g. _"Do you prefer a denser layout or roomy spacing?"_).
|
|
168
|
-
3. After they answer (or decline), call \`change-appearance\` if appropriate, do whatever the second answer implies (e.g. set a calendar visual preference), and then write \`application_state.personalization\` = \`{ "done": true }\` via \`writeAppState\` so this flow doesn't run again.
|
|
169
|
-
|
|
170
|
-
If the user's first message is clearly already on-task (e.g. "what's on my calendar today?"), answer it first — but still surface ONE line at the end like _"By the way, want me to set a theme for your workspace? Try \`change-appearance warm\` or just ask."_ — then mark personalization done so the offer never repeats.
|
|
171
|
-
|
|
172
|
-
Do NOT block on this flow. If the user ignores it, just proceed; never re-ask the personalization questions in later sessions.
|
|
173
|
-
`;
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
* agent-chat-plugin.ts has a single clean import.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
export {
|
|
7
|
-
buildFrameworkCore,
|
|
8
|
-
FIRST_SESSION_PERSONALIZATION,
|
|
9
|
-
} from "./framework-core.js";
|
|
6
|
+
export { buildFrameworkCore } from "./framework-core.js";
|
|
10
7
|
export { buildFrameworkCoreCompact } from "./framework-core-compact.js";
|
|
11
8
|
export {
|
|
12
9
|
sharedRule8,
|
|
@@ -9,10 +9,8 @@ import {
|
|
|
9
9
|
import { ExtensionsSidebarSection } from "@agent-native/core/client/extensions";
|
|
10
10
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
11
11
|
import {
|
|
12
|
-
IconActivity,
|
|
13
12
|
IconArchive,
|
|
14
13
|
IconBrain,
|
|
15
|
-
IconDatabase,
|
|
16
14
|
IconDots,
|
|
17
15
|
IconEdit,
|
|
18
16
|
IconLayoutSidebarLeftCollapse,
|
|
@@ -48,18 +46,6 @@ const navItems = [
|
|
|
48
46
|
href: "/",
|
|
49
47
|
view: "chat",
|
|
50
48
|
},
|
|
51
|
-
{
|
|
52
|
-
icon: IconActivity,
|
|
53
|
-
labelKey: "navigation.observability",
|
|
54
|
-
href: "/observability",
|
|
55
|
-
view: "observability",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
icon: IconDatabase,
|
|
59
|
-
labelKey: "navigation.database",
|
|
60
|
-
href: "/database",
|
|
61
|
-
view: "database",
|
|
62
|
-
},
|
|
63
49
|
{
|
|
64
50
|
icon: IconBrain,
|
|
65
51
|
labelKey: "settings.agentTitle",
|
|
@@ -454,6 +454,7 @@ const messages = {
|
|
|
454
454
|
invite: "Invitar",
|
|
455
455
|
embed: "Insertar",
|
|
456
456
|
shareLink: "Enlace para compartir",
|
|
457
|
+
shareWithHumans: "Compartir con personas",
|
|
457
458
|
shareWithAgents: "Compartir con agentes",
|
|
458
459
|
copyAgentPrompt: "Copiar indicación para agente",
|
|
459
460
|
agentPrompt:
|
|
@@ -454,6 +454,7 @@ const messages = {
|
|
|
454
454
|
invite: "Inviter",
|
|
455
455
|
embed: "Intégrer",
|
|
456
456
|
shareLink: "Lien de partage",
|
|
457
|
+
shareWithHumans: "Partager avec des personnes",
|
|
457
458
|
shareWithAgents: "Partager avec les agents",
|
|
458
459
|
copyAgentPrompt: "Copier le prompt pour agent",
|
|
459
460
|
agentPrompt:
|
|
@@ -437,6 +437,7 @@ const messages = {
|
|
|
437
437
|
invite: "आमंत्रित करें",
|
|
438
438
|
embed: "एम्बेड",
|
|
439
439
|
shareLink: "शेयर लिंक",
|
|
440
|
+
shareWithHumans: "लोगों के साथ साझा करें",
|
|
440
441
|
shareWithAgents: "एजेंटों के साथ साझा करें",
|
|
441
442
|
copyAgentPrompt: "एजेंट प्रॉम्प्ट कॉपी करें",
|
|
442
443
|
agentPrompt:
|
|
@@ -451,6 +451,7 @@ const messages = {
|
|
|
451
451
|
invite: "Convidar",
|
|
452
452
|
embed: "Incorporar",
|
|
453
453
|
shareLink: "Link de compartilhamento",
|
|
454
|
+
shareWithHumans: "Compartilhe com pessoas",
|
|
454
455
|
shareWithAgents: "Compartilhe com agentes",
|
|
455
456
|
copyAgentPrompt: "Copiar prompt para agente",
|
|
456
457
|
agentPrompt:
|
|
@@ -4,6 +4,7 @@ import { eq } from "drizzle-orm";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
|
+
import { invalidatePublicFormCache } from "../server/lib/public-form-ssr.js";
|
|
7
8
|
|
|
8
9
|
export default defineAction({
|
|
9
10
|
description:
|
|
@@ -37,6 +38,7 @@ export default defineAction({
|
|
|
37
38
|
.delete(schema.responses)
|
|
38
39
|
.where(eq(schema.responses.formId, args.id));
|
|
39
40
|
await db.delete(schema.forms).where(eq(schema.forms.id, args.id));
|
|
41
|
+
invalidatePublicFormCache(existing);
|
|
40
42
|
return { success: true, purged: true };
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -46,6 +48,8 @@ export default defineAction({
|
|
|
46
48
|
.set({ deletedAt: now, updatedAt: now })
|
|
47
49
|
.where(eq(schema.forms.id, args.id));
|
|
48
50
|
|
|
51
|
+
invalidatePublicFormCache(existing);
|
|
52
|
+
|
|
49
53
|
return { success: true, purged: false, deletedAt: now };
|
|
50
54
|
},
|
|
51
55
|
});
|
|
@@ -23,6 +23,7 @@ import { z } from "zod";
|
|
|
23
23
|
|
|
24
24
|
import { getDb, schema } from "../server/db/index.js";
|
|
25
25
|
import { applyFieldOps } from "../server/lib/merge-fields.js";
|
|
26
|
+
import { invalidatePublicFormCache } from "../server/lib/public-form-ssr.js";
|
|
26
27
|
import { assertValidFields } from "../server/lib/validate-fields.js";
|
|
27
28
|
import type { FormField } from "../shared/types.js";
|
|
28
29
|
import { assertPublishableForm } from "./lib/assert-publishable-form.js";
|
|
@@ -139,6 +140,8 @@ export default defineAction({
|
|
|
139
140
|
.set({ fields: JSON.stringify(nextFields), updatedAt: now })
|
|
140
141
|
.where(eq(schema.forms.id, args.id));
|
|
141
142
|
|
|
143
|
+
invalidatePublicFormCache(existing);
|
|
144
|
+
|
|
142
145
|
return { id: args.id, fields: nextFields, updatedAt: now };
|
|
143
146
|
});
|
|
144
147
|
},
|
|
@@ -4,6 +4,7 @@ import { eq } from "drizzle-orm";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
|
+
import { invalidatePublicFormCache } from "../server/lib/public-form-ssr.js";
|
|
7
8
|
|
|
8
9
|
export default defineAction({
|
|
9
10
|
description:
|
|
@@ -31,6 +32,8 @@ export default defineAction({
|
|
|
31
32
|
.set({ deletedAt: null, updatedAt: now })
|
|
32
33
|
.where(eq(schema.forms.id, args.id));
|
|
33
34
|
|
|
35
|
+
invalidatePublicFormCache(existing);
|
|
36
|
+
|
|
34
37
|
return { success: true };
|
|
35
38
|
},
|
|
36
39
|
});
|
|
@@ -5,6 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
7
|
import { assertIntegrationUrlsAllowed } from "../server/lib/integrations.js";
|
|
8
|
+
import { invalidatePublicFormCache } from "../server/lib/public-form-ssr.js";
|
|
8
9
|
import { assertValidFields } from "../server/lib/validate-fields.js";
|
|
9
10
|
import type { FormField, FormSettings } from "../shared/types.js";
|
|
10
11
|
import { assertPublishableForm } from "./lib/assert-publishable-form.js";
|
|
@@ -136,6 +137,8 @@ export default defineAction({
|
|
|
136
137
|
.where(eq(schema.forms.id, args.id))
|
|
137
138
|
.limit(1);
|
|
138
139
|
|
|
140
|
+
invalidatePublicFormCache(existing, row);
|
|
141
|
+
|
|
139
142
|
return {
|
|
140
143
|
id: row!.id,
|
|
141
144
|
title: row!.title,
|
|
@@ -1468,10 +1468,10 @@ function ResultsContent({ formId, form }: { formId: string; form: any }) {
|
|
|
1468
1468
|
key={response.id}
|
|
1469
1469
|
className="border-b border-border hover:bg-muted/20"
|
|
1470
1470
|
>
|
|
1471
|
-
<td className="px-4 py-2.5 text-xs text-muted-foreground">
|
|
1471
|
+
<td className="px-4 py-2.5 align-top text-xs text-muted-foreground">
|
|
1472
1472
|
{responses.length - idx}
|
|
1473
1473
|
</td>
|
|
1474
|
-
<td className="min-w-36 px-4 py-2.5 text-xs text-muted-foreground whitespace-nowrap">
|
|
1474
|
+
<td className="min-w-36 px-4 py-2.5 align-top text-xs text-muted-foreground whitespace-nowrap">
|
|
1475
1475
|
{format(new Date(response.submittedAt), "MMM d, h:mm a")}
|
|
1476
1476
|
</td>
|
|
1477
1477
|
{hasSubmitterEmail && (
|
|
@@ -428,10 +428,10 @@ export function ResponsesPage() {
|
|
|
428
428
|
key={response.id}
|
|
429
429
|
className="border-b border-border transition-[background-color] duration-150 hover:bg-muted/20 motion-reduce:transition-none"
|
|
430
430
|
>
|
|
431
|
-
<td className="px-4 py-2.5 text-xs text-muted-foreground">
|
|
431
|
+
<td className="px-4 py-2.5 align-top text-xs text-muted-foreground">
|
|
432
432
|
{filteredSorted.length - idx}
|
|
433
433
|
</td>
|
|
434
|
-
<td className="min-w-36 px-4 py-2.5 text-xs text-muted-foreground whitespace-nowrap">
|
|
434
|
+
<td className="min-w-36 px-4 py-2.5 align-top text-xs text-muted-foreground whitespace-nowrap">
|
|
435
435
|
{formatDate(response.submittedAt, {
|
|
436
436
|
month: "short",
|
|
437
437
|
day: "numeric",
|
|
@@ -53,6 +53,7 @@ export const getPublicForm = defineEventHandler(async (event: H3Event) => {
|
|
|
53
53
|
const settings = JSON.parse(row.settings) as FormSettings;
|
|
54
54
|
const result = {
|
|
55
55
|
id: row.id,
|
|
56
|
+
updatedAt: row.updatedAt,
|
|
56
57
|
title: row.title,
|
|
57
58
|
description: row.description,
|
|
58
59
|
fields: JSON.parse(row.fields),
|
|
@@ -22,14 +22,38 @@ import { getDb, schema } from "../db/index.js";
|
|
|
22
22
|
const cache = new Map<string, { data: any; ts: number }>();
|
|
23
23
|
const TTL = 60_000;
|
|
24
24
|
|
|
25
|
+
type PublicFormCacheKeys = {
|
|
26
|
+
id?: string | null;
|
|
27
|
+
slug?: string | null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export function invalidatePublicFormCache(
|
|
31
|
+
...forms: Array<PublicFormCacheKeys | null | undefined>
|
|
32
|
+
) {
|
|
33
|
+
for (const form of forms) {
|
|
34
|
+
for (const key of [form?.id, form?.slug]) {
|
|
35
|
+
if (!key) continue;
|
|
36
|
+
cache.delete(key);
|
|
37
|
+
const versionPrefix = `${key}?v=`;
|
|
38
|
+
for (const cachedKey of cache.keys()) {
|
|
39
|
+
if (cachedKey.startsWith(versionPrefix)) cache.delete(cachedKey);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
25
45
|
function getCached(key: string) {
|
|
26
46
|
const entry = cache.get(key);
|
|
27
47
|
if (entry && Date.now() - entry.ts < TTL) return entry.data;
|
|
28
48
|
return null;
|
|
29
49
|
}
|
|
30
50
|
|
|
31
|
-
export async function getPublicFormBySlugOrId(
|
|
32
|
-
|
|
51
|
+
export async function getPublicFormBySlugOrId(
|
|
52
|
+
slugOrId: string,
|
|
53
|
+
version?: string,
|
|
54
|
+
) {
|
|
55
|
+
const cacheKey = version ? `${slugOrId}?v=${version}` : slugOrId;
|
|
56
|
+
const cached = getCached(cacheKey);
|
|
33
57
|
if (cached) return cached;
|
|
34
58
|
|
|
35
59
|
const db = getDb();
|
|
@@ -66,7 +90,7 @@ export async function getPublicFormBySlugOrId(slugOrId: string) {
|
|
|
66
90
|
settings: toPublicFormSettings(settings),
|
|
67
91
|
};
|
|
68
92
|
|
|
69
|
-
cache.set(
|
|
93
|
+
cache.set(cacheKey, { data: result, ts: Date.now() });
|
|
70
94
|
return result;
|
|
71
95
|
}
|
|
72
96
|
|
|
@@ -103,6 +127,7 @@ const FALLBACK_PUBLIC_FORM_ORIGIN = "http://agent-native.local";
|
|
|
103
127
|
function parsePublicFormUrl(url: string): {
|
|
104
128
|
pathname: string;
|
|
105
129
|
origin?: string;
|
|
130
|
+
version?: string;
|
|
106
131
|
} {
|
|
107
132
|
try {
|
|
108
133
|
const parsed = new URL(url, FALLBACK_PUBLIC_FORM_ORIGIN);
|
|
@@ -110,6 +135,7 @@ function parsePublicFormUrl(url: string): {
|
|
|
110
135
|
return {
|
|
111
136
|
pathname: parsed.pathname,
|
|
112
137
|
origin: isAbsolute ? parsed.origin : undefined,
|
|
138
|
+
version: parsed.searchParams.get("v") || undefined,
|
|
113
139
|
};
|
|
114
140
|
} catch {
|
|
115
141
|
return { pathname: url.split("?")[0] || "/" };
|
|
@@ -261,7 +287,9 @@ export async function renderPublicFormHtml(
|
|
|
261
287
|
? pathname.slice(basePath.length)
|
|
262
288
|
: pathname;
|
|
263
289
|
const slugOrId = decodeURIComponent(pathWithoutBase.replace(/^\/f\//, ""));
|
|
264
|
-
const form = slugOrId
|
|
290
|
+
const form = slugOrId
|
|
291
|
+
? await getPublicFormBySlugOrId(slugOrId, parsedUrl.version)
|
|
292
|
+
: null;
|
|
265
293
|
|
|
266
294
|
if (!form) {
|
|
267
295
|
return { html: notFoundPage(parsedUrl.origin), status: 404 };
|
|
@@ -402,10 +430,25 @@ function renderFormPage(
|
|
|
402
430
|
<script>
|
|
403
431
|
(function(){
|
|
404
432
|
var FORM_ID = ${JSON.stringify(form.id)};
|
|
433
|
+
var FORM_VERSION = ${JSON.stringify(form.updatedAt || "")};
|
|
434
|
+
var PUBLIC_FORM_API = ${JSON.stringify(`${appBasePath}/api/forms/public/${encodeURIComponent(form.slug || form.id)}`)};
|
|
405
435
|
var REDIRECT = ${JSON.stringify(safeRedirectUrl(settings.redirectUrl))};
|
|
406
436
|
var TURNSTILE_KEY = ${JSON.stringify(turnstileSiteKey)};
|
|
407
437
|
var FIELDS = ${JSON.stringify(fields.map((f) => ({ id: f.id, type: f.type, required: f.required, validation: f.validation, label: f.label, conditional: f.conditional })))};
|
|
408
438
|
|
|
439
|
+
function revalidateFormVersion() {
|
|
440
|
+
fetch(PUBLIC_FORM_API, { cache: "no-store" })
|
|
441
|
+
.then(function(response) { return response.ok ? response.json() : null; })
|
|
442
|
+
.then(function(latest) {
|
|
443
|
+
if (!latest || typeof latest.updatedAt !== "string" || !latest.updatedAt || latest.updatedAt === FORM_VERSION) return;
|
|
444
|
+
var currentUrl = new URL(window.location.href);
|
|
445
|
+
currentUrl.searchParams.set("v", latest.updatedAt);
|
|
446
|
+
window.location.replace(currentUrl.toString());
|
|
447
|
+
})
|
|
448
|
+
.catch(function() {});
|
|
449
|
+
}
|
|
450
|
+
revalidateFormVersion();
|
|
451
|
+
|
|
409
452
|
// Theme toggle
|
|
410
453
|
var html = document.documentElement;
|
|
411
454
|
var saved = localStorage.getItem("theme");
|